众所周知,Spring 是目前市面上最主流的一款功能非常强大的框架,中文意思是春天,也让我们开发人员从JSP、sevlet的高耦合的开发中彻底的解救出来。废话少说,接下来就进行详细介绍。
Spring是一个开源框架,Spring的核心是控制反转(IOC)和面向切面(AOP)。
简单来说,Spring是一个分层的JavaSE/EE full-stack(一站式) 轻量级开源框架。
轻量级:与EJB对比,依赖资源少,销毁的资源少。
分层: 一站式,每一个层都提供的解决方案
Spring 出现是为了解决JavaEE 实际问题:
方便解耦,简化开发 (IOC)
Spring就是一个大工厂(容器),可以将所有对象创建和依赖关系维护,交给Spring管理
Spring工厂是用于生成bean
AOP编程的支持
Spring提供面向切面编程,可以方便的实现对程序进行权限拦截、运行监控等功能
声明式事务的支持
只需要通过配置就可以完成对事务的管理,而无需手动编程
方便程序的测试
Spring对Junit4支持,可以通过注解方便的测试Spring程序
方便集成各种优秀框架
Spring不排斥各种优秀的开源框架,其内部提供了对各种优秀框架(如:Struts、Hibernate、MyBatis、Quartz等)的直接支持
降低JavaEE API的使用难度
Spring 对JavaEE开发中非常难用的一些API(JDBC、JavaMail、远程调用等),都提供了封装,使这些API应用难度大大降低
基于这些特性,我们也会俗称Spring为开发架构的粘合剂。
可以访问官网进行自主学习:https://spring.io/
Spring框架至今已集成了20多个模块,这些模块分布在以下模块中:
核心容器(Core Container)
数据访问/集成(Data Access/Integration)层
Web层
AOP(Aspect Oriented Programming)模块
植入(Instrumentation)模块
消息传输(Messaging)
测试(Test)模块
Spring所有功能都依赖于这两个核心
注意:IOC和AOP并不是一种技术,而是一种思想,这点要清楚。
接下来就来讲一下IOC
IOC介绍:IOC 全称为 Inversion of Control,翻译为 “控制反转”。
控制:控制对象的创建与销毁
反转:将对象的控制权(创建与销毁)交给Spring的IOC容器。
作用:解耦。
由于Java是面向对象开发,开发过程中由N个对象构成,各对象互相合作完成需求。但是此过程存在一个很大的问题,就是各个对象间耦合度太高,导致后期维护困难。
而Spring提供了一种IOC思想,就是引用“第三方”:IOC容器实现具有依赖关系的对象之间的解耦。全部对象的控制权都交给IOC容器,包括创建、销毁,这样各对象间就解除了关系,独立存在。
其他解释:
什么是ioc:控制反转,以前我们要获取对象,我们自己new.主动获取。现在有了工厂模式,我们需要获取对象,是工厂创建,我们被动接受工厂创建的对象.这就是控制反转.说白了ioc就是工厂模式.
spring框架提供了一个大工厂接口:ApplicationContext(父接口Beanfactroy)
spring-IOC的配置采取的是什么类型?
spring使用XML格式的文件存储配置
<bean id="唯一标识"
class="实现类的全限定名">
bean>
spring-IOC是怎么加载配置文件的呢?
ApplicationContext工厂使用ClassPathXmlApplicationContext加载配置文件
基于多个实现类需要进行功能切换,我们只需要修改配置文件,不需要改java代码,所以不需要重新编译。
使用一个入门小案例来讲解
使用ApplicationContext:spring-IOC容器创建对象
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<groupId>com.vv.springgroupId>
<artifactId>spring-iocartifactId>
<version>1.0-SNAPSHOTversion>
<name>spring-iocname>
<url>http://www.example.comurl>
<properties>
<project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
<spring.version>5.1.11.RELEASEspring.version>
properties>
<dependencies>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-contextartifactId>
<version>5.0.6.RELEASEversion>
dependency>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>4.12version>
dependency>
dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-compiler-pluginartifactId>
<version>3.2version>
<configuration>
<source>1.8source>
<target>1.8target>
configuration>
plugin>
plugins>
build>
project>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="accountDao" class="com.vv.spring.dao.Impl.AccountDaoImpl"/>
<bean id="accountService" class="com.vv.spring.service.Impl.AccountServiceImpl"/>
beans>
public class SpringTest {
public static void main(String[] args) {
//1.创建spring的工厂
ApplicationContext ac = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
//2.通过spring的工厂获取对象
Object userService = ac.getBean("userService");
System.out.println(userService);
}
}
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="userService" scope="prototype" init-method="init" destroy-method="destroy" class="com.itheima.service.impl.UserServiceImpl">bean>
beans>
UserServiceImpl
Test
public class SpringTest {
public static void main(String[] args) {
System.out.println("************工厂初始化start***********");
ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
System.out.println("************工厂初始化end*************");
//通过spring的工厂获取对象
Object userService = ac.getBean("userService");
Object userService2 = ac.getBean("userService");
System.out.println(userService);
System.out.println(userService2);
//销毁工厂
System.out.println("*************销毁工厂*****************");
ac.close();
}
}
运行结果:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="userService" class="com.vv.service.impl.UserServiceImpl">bean>
<bean id="userService2" class="com.vv.utils.BeanFactory" factory-method="getUserService">bean>
<bean id="factoryBean2" class="com.vv.utils.BeanFactory2">bean>
<bean id="userService3" factory-bean="factoryBean2" factory-method="getUserService" >bean>
beans>
public class UserServiceImpl implements UserService {
//无参构造
public UserServiceImpl() {
System.out.println("UserServiceImpl的无参构造被调用了");
}
}
public class BeanFactory {
//工厂类的静态方法
public static UserService getUserService(){
System.out.println("工厂类的静态方法");
return new UserServiceImpl();
}
}
public class BeanFactory2 {
//工厂类的动态方法
public UserService getUserService(){
System.out.println("工厂类的动态方法");
return new UserServiceImpl();
}
}
Dependency Injection (依赖注入):
spring创建对象的时候,给对象的属性赋值,就是依赖注入。
注意是spring创建对象!!!
applicationContext.xml
<bean id="userService" class="com.vv.service.impl.UserServiceImpl">
<constructor-arg name="age" value="23" >constructor-arg>
<constructor-arg name="game" value="LOL">constructor-arg>
<constructor-arg name="username" value="张三">constructor-arg>
<constructor-arg name="userDao" ref="userDao">constructor-arg>
bean>
<bean id="userService2" class="com.vv.service.impl.UserServiceImpl">
<constructor-arg index="1" value="23" >constructor-arg>
<constructor-arg index="2" value="LOL">constructor-arg>
<constructor-arg index="0" value="张四">constructor-arg>
<constructor-arg index="3" ref="userDao">constructor-arg>
bean>
<bean id="userService3" class="com.vv.service.impl.UserServiceImpl">
<constructor-arg type="java.lang.Integer" value="23" >constructor-arg>
<constructor-arg type="java.lang.String" value="王五">constructor-arg>
<constructor-arg type="java.lang.String" value="LOL">constructor-arg>
<constructor-arg type="com.vv.dao.UserDao" ref="userDao">constructor-arg>
bean>
UserServiceImpl
public class UserServiceImpl implements UserService {
private String username;
private Integer age;
private String game;
private UserDao userDao;
//有参构造
public UserServiceImpl(String username, Integer age, String game, UserDao userDao) {
this.username = username;
this.age = age;
this.game = game;
this.userDao = userDao;
}
public UserServiceImpl() {
}
@Override
public void login() {
userDao.findUserByUser();
}
}
Test
public class SpringTest {
//这是一个servlet
public static void main(String[] args) {
//调用service的方法
ApplicationContext ac = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
UserService userService = (UserService)ac.getBean("userService");
userService.login();
}
}
applicationContext.xml
<!-- 属性的set方法 -->
<bean id="userService" class="com.vv.service.impl.UserServiceImpl">
<!--
name:用来确定属性的。
name属性的值是set的方法名去掉set后的驼峰命名名字。
value:基本类型的属性赋值
ref:引用型类型的属性赋值
-->
<property name="username" value="赵六"></property>
<property name="age" value="25"></property>
<property name="game" value="王者荣耀"></property>
<property name="userDao" ref="userDao"></property>
</bean>
UserServiceImpl
public class UserServiceImpl implements UserService {
private String username;
private Integer age;
private String game;
private UserDao userDao;
public UserServiceImpl(String username, Integer age, String game, UserDao userDao) {
this.username = username;
this.age = age;
this.game = game;
this.userDao = userDao;
}
public void setUsername(String username) {
this.username = username;
}
public void setAge(Integer age) {
this.age = age;
}
public void setGame(String game) {
this.game = game;
}
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public UserServiceImpl() {
}
@Override
public void login() {
userDao.findUserByUser();
}
}
Test
public class SpringTest {
//这是一个servlet
public static void main(String[] args) {
//调用service的方法
ApplicationContext ac = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
UserService userService = (UserService)ac.getBean("userService");
userService.login();
}
}
UserServiceImpl
public class UserServiceImpl2 implements UserService {
private String[] gameNames;
private List<String> dogType;
private Set<String> catType;
private Map<String,String> map;
public void setGameNames(String[] gameNames) {
this.gameNames = gameNames;
}
public void setDogType(List<String> dogType) {
this.dogType = dogType;
}
public void setCatType(Set<String> catType) {
this.catType = catType;
}
public void setMap(Map<String, String> map) {
this.map = map;
}
@Override
public void login(){
}
}
applicationContext.xml
<bean id="userService" class="com.vv.service.impl.UserServiceImpl2">
<property name="gameNames">
<array>
<value>LOLvalue>
<value>PUBGvalue>
<value>王者荣耀value>
array>
property>
<property name="dogType">
<list>
<value>博美value>
<value>柴犬value>
<value>哈士奇value>
list>
property>
<property name="catType">
<set>
<value>英短value>
<value>橘猫value>
<value>无毛猫value>
set>
property>
<property name="map">
<map>
<entry value="科比" key="name">entry>
map>
bean>
Spring提供的JdbcTemplate和mybatis框架一样,都是对jdbc的封装,用于支撑持久层的操作,但企业开发中mybatis应用较广。
下面就对JdbcTemplate的用法进行简单介绍。
1、搭建数据库环境;
2、创建工程导入依赖
<dependencies>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-jdbcartifactId>
<version>5.0.6.RELEASEversion>
dependency>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>4.12version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-contextartifactId>
<version>5.0.6.RELEASEversion>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>5.1.38version>
dependency>
dependencies>
3、创建pojo层
4、实现dao层接口和实现类
5、实现service层接口和实现类
6、通过配置文件实现IOC和依赖注入
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--accountService-->
<bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl">
<!--注入accountDao-->
<property name="accountDao" ref="accountDao"></property>
</bean>
<!--accountDao-->
<bean id="accountDao" class="com.itheima.dao.impl.AccountDaoImpl">
<!--依赖注入jdbcTemplate-->
<property name="jdbcTemplate" ref="jdbcTemplate"></property>
</bean>
<!--jdbcTemplate对象-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<!--依赖注入数据源-->
<constructor-arg name="dataSource" ref="dataSource"></constructor-arg>
</bean>
<!--创建数据源对象-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<!-- set方法依赖注入-->
<property name="username" value="root"></property>
<property name="password" value="root"></property>
<property name="url" value="jdbc:mysql://localhost:3306/itheima115_spring_day02"></property>
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
</bean>
</beans>
7、创建测试用例完成测试
8、优化-加载外部数据源
pom.xml
<dependency>
<groupId>com.alibabagroupId>
<artifactId>druidartifactId>
<version>1.0.9version>
dependency>
<dependency>
<groupId>c3p0groupId>
<artifactId>c3p0artifactId>
<version>0.9.1.2version>
dependency>
<dependency>
<groupId>commons-dbcpgroupId>
<artifactId>commons-dbcpartifactId>
<version>1.4version>
dependency>
applicationContext.xml
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="username" value="${jdbc.username}">property>
<property name="password" value="${jdbc.password}">property>
<property name="url" value="${jdbc.url}">property>
<property name="driverClassName" value="${jdbc.driverClass}">property>
bean>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="user" value="${jdbc.username}">property>
<property name="password" value="${jdbc.password}">property>
<property name="jdbcUrl" value="${jdbc.url}">property>
<property name="driverClass" value="${jdbc.driverClass}">property>
bean>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="username" value="${jdbc.username}">property>
<property name="password" value="${jdbc.password}">property>
<property name="url" value="${jdbc.url}">property>
<property name="driverClassName" value="${jdbc.driverClass}">property>
bean>
注解开发的优点:提高开发效率。
主要分为下面几个类型使用:
创建对象:@component; @Controller; @Service; @Repository;
依赖注入:@Autowired; @Qualifier; @Resource(name=beanid); @Value;
生命周期:@Scope; @PostConstruct; @PreDestroy;
纯注解开发相关:@Configuration; @ComponentScan; @PropertySource; @Import; @Bean
Spring整合单元测试:@RunWith; @ContextConfiguration;
具体的使用方法还没来得及总结,有空发出来。