一、Spring简介
(一) Spring是什么?
Spring是一个开源的控制反转(IoC)和面向切面(AOP)的容器框架, 用来简化企业开发的。目前版本主要用:3.x 4.x 5.x。
(二)为什么使用Spring
- 降低组件之间的耦合度,实现软件各层之间解耦合 Controller——>Service——>DAO
- 让代码结构更良好
- 面向接口编程
- 高低原则:高内聚、低耦合
- 开闭原则:对扩展开放、对修改关闭
- 提供了许多技术支持
- 提供了辅助类,如:JdbcTemplate、HibernateTemplate、StringUtils、CollectionUtils、 StreamUtils等
- 提供了各种服务,如:事务管理服务、消息服务等
- 提供单例模式
- 提供了AOP技术
- 对主流框架提供了集成支持
- 集成MyBatis、Hibernate、JPA、Struts等
(三) Spring体系结构
IoC、AOP、Data Access、Web
二、核心概念
(一) IOC (Inversion of Control 控制反转)
IOC可以看成是一个用于管理各类Bean的容器,控制反转就是指本身不负责依赖对象的创建及维护,依赖对象的创建及维护交由外部容器来负责,这 样控制权发生转移,控制权转移就是控制反转。理解:就是一个Bean交给一个容器去创建和维护,也就是IOC容器是管理Bean的容器
具体代码示例:
(二) DI (dependency injection 依赖注入)
依赖注入就是指在运行期,由外部容器动态的将依赖对象注入到组件。IOC可以创建和维护多个Bean,当IOC容器中的一个Bean,需要将另外一个Bean装配(注入)进去的时候,这个叫做依赖注入,这两个Bean都在IOC容器中。
三、创建SpringIOC流程
(一) 添加jar依赖包
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.3.6</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.6</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>5.3.6</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>5.3.6</version>
</dependency>
(二) 核心配置文件
<bean class="java.lang.Class" factory-method="forName">
<constructor-arg name="className" value="com.mysql.cj.jdbc.Driver"/>
</bean>
<bean id="connection" class="java.sql.DriverManager" factory-method="getConnection">
<constructor-arg name="url" value="jdbc:mysql://localhost:3306/mydb?useSSL=false&serverTimezone=UTC"/>
<constructor-arg name="user" value="root"/>
<constructor-arg name="password" value="123456"/>
</bean>
<bean id="statemement" factory-bean="connection" factory-method="createStatement"/>
<bean id="result" factory-bean="statemement" factory-method="executeQuery">
<constructor-arg name="sql" value="select * from customer"/>
</bean>
(三) 创建IOC容器,将xml配置文件加载到容器
此处的IOC容器创建有两种方式:
- ApplicationContext
- BeanFactory
ApplicationContext和BeanFactory都是一个接口,ApplicationContext他有两个实现类:
- ClassPathXmlApplicationContext:他的意思是:从相对路加载核心配置文件xml
- FileSystemXmlApplicationContext:从文件系统的绝对路径加载核心配置文件 xml
BeanFactory有一个实现类:
- XmlBeanFactory(已过时)
对于XmlBeanFactory而言,他不是直接加载核心配置文件,而是先要将核心配置文件 xml 加载到 Resource数据空间中,而Resource也有两个实现类:
- ClassPathResource:从相对路加载核心配置文件xml
- FileSystemResource:从文件系统的绝对路径加载核心配置文件 xml
@Test
public void test11() {
// TODO: 2021/7/5 第一种创建IOC容器的方法:他创建的IOC容器管理Bean的时机为创建IOC即创建Bean
ApplicationContext ac = new ClassPathXmlApplicationContext("ioc1/ioc1.xml");
ResultSet result = (ResultSet) ac.getBean("result");
// TODO: 2021/7/5 第二种方式:(已经过时),Bean的创建时机为调用getBean()方法的时候
Resource classPathResource = new ClassPathResource("ioc1/ioc1.xml");
BeanFactory xmlBeanFactory = new XmlBeanFactory(classPathResource);
ResultSet result1 = (ResultSet) xmlBeanFactory.getBean("result");
}
四、通过配置文件给Bean装配数据
Spring容器加载配置文件后,在为Spring容器中形成Bean,容器里的Bean需要装配数据,也就是给Bean中的属性注入值,这个过程叫做数据装配。装配的数据有两种类型,一是基本数据类型的装配;二是自定义Bean、集合,properties数据的装配。
(一)基本数据类型的装配(共19种)
数据类型:byte,short,int,long,float,double,char,boolean,与其相对应的包装类,再加上:String,Class,Resource.
1.基本数据类型的装配
- 第一步:定义一个JavaBean
public class User {
private String username;
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
- 第二步:在配置文件中定义Bean并装配基本类型数据
<bean id="newuser" class="sun.com.one.user.User">
<property name="password" value="122333"/>
<property name="username" value="hehehehe"/>
</bean>
2.自定义Bean、集合等其他数据类型的装配
自定义Bean,集合,Properties数据的装配相对而言较为复杂,其与基本数据类型的装配主要的区别是:基本数据类型都是用value来装配数据,而自定义Bean等是用ref来装配数据。下面分别对数组、集合、Properties来进行数据装配,首先得设计Bean
1.Bean的设计
public class UserViceImpl implements UserVice {
private UserDao userDao;
private Integer[] arrays;
private List<User> userList;
private Set<User> userset;
private Map<User,Class> userMap;
private Properties properties;
private String strName = "javahello";
}
2.自定义Bean
<bean id="userdal" class="sun.com.one.dao.impl.UserDaoImpl"/>
<bean id="userObject" class="sun.com.one.service.Impl.UserViceImpl">
<!-- TODO:这个定义为自定义Bean的装配 -->
<property name="userDao" ref="userdal"/>
</bean>
3. Bean中的数组装配
<bean id="userObject" class="sun.com.one.service.Impl.UserViceImpl">
<!-- TODO: -->
<property name="arrays">
<array> <!-- 在这个也可以用list标签-->
<value>1</value>
<value>2</value>
</array>
</property>
</bean>
4. List集合的装配
List集合的装配,根据保存到List集合的Bean,有两种方式可以进行装配。一种是在在property代码块中创建Bean直接进行装配,另一种情况是是先创建Bean,在进行装配,具体示例代码如下:
<bean id="userObject" class="sun.com.one.service.Impl.UserViceImpl">
<property name="userList">
<list> <!-- TOO:由于list可以重复,所以放进去几个就是几个.而set不允许重合,所以生命的一般都会去掉-->
<!-- TODO:这个地方使用里面调用新生成的Bean -->
<bean class="sun.com.one.user.User">
<property name="username" value="python"/>
<property name="password" value="123456"/>
</bean>
<bean class="sun.com.one.user.User">
<property name="username" value="hello"/>
<property name="password" value="123456"/>
</bean>
<!-- TODO:先创建Bean,再装配 -->
<ref bean="newuser"/> <!-- 外部定义的Bean -->
</list>
</property>
</bean>
5. Set集合的装配
Set集合的装配和List集合的装配方式是一样的,唯一的区别是Set集合是无序不可重复的,所以,如果装配两个相同的内容时,在Bean中的Set集合中,把删除重复的,只装配一个对象到Bean中的Set集合中。
<bean id="userObject" class="sun.com.one.service.Impl.UserViceImpl">
<!-- TODO:对set集合注入的方法 -->
<property name="userset">
<set>
<ref bean="newuser"/>
<ref bean="newuser"/>
<!-- TODO:上面两个装配的内容一样,只会保留一个在Bean中的Set集合中 -->
<bean class="sun.com.one.user.User">
<property name="username" value="C++"/>
<property name="password" value="123456"/>
</bean>
</set>
</property>
</bean>
6. Map集合的装配
Map集合的装配相对而言比较简单,装配前,得分析自定义Bean中的Map集合确定的泛型类型,如果泛型都是基本类型,可以用key 和 value来确定,如果是Bean类型,则需要用ref来确定。有这么几中情形:一是key,value,另一种是key-ref 和 value-ref 具体示例代码:
<bean id="userObject" class="sun.com.one.service.Impl.UserViceImpl">
<!-- TODO:map集合的注入 -->
<property name="userMap">
<map>
<!-- TODO:ref都表示对其他bean的引用 -->
<entry key-ref="newuser" value="java.lang.Integer"/>
</map>
</property>
</bean>
7. Properties属性类的装配
<bean id="userObject" class="sun.com.one.service.Impl.UserViceImpl">
<property name="properties">
<props>
<prop key="key1">vaule1</prop>
<prop key="key2">vaule2</prop>
</props>
</property>
</bean>
8.给带有属性装配null
在自定义Bean中,如果属性被显示的赋予了值,可以通过配置文件给该属性装配null
<bean id="userObject" class="sun.com.one.service.Impl.UserViceImpl">
<!-- TODO:给带有属性的值装配null -->
<property name="strName">
<null/>
</property>
</bean>
(二)关于数据装配的总结:
通过ClasspathXmlApplicationContext,FileSystemXmlApplicationContext,或者通过过时的XmlBeanFactory加载配置文件形成的Spring容器,在里面产生Bean,对Bean定义的各种属性都有不同的加载方法。
五、bean生命周期
(一)生命周期各阶段
Bean的生命周期重点突出两个位置,一是初始化;二是销毁前调用;
- 初始化方法:init-method=“Bean中的方法 名”
- 销毁方法:destroy-method=“Bean中的方法名”
初始化方法是在数据装配完成之后,通过调用指定Bean中的方法,销毁方法是在Bean销毁之前调用
<bean id="userioc1" class="ioc1.UserIoc1Bean" init-method="initmethod" destroy-method="destorymethod">
<property name="username" value="hellojava"/>
<property name="age" value="20"/>
</bean>