spring教程
IOC配置详解
1.1. 容器概述
**
ApplicationContext是Spring IoC容器实现的代表,它负责实例化,配置和组装Bean。容器通过读取配置元数据获取有关实例化、配置和组装哪些对象的说明 。配置元数据可以使用XML、Java注解或Java代码来呈现。它允许你处理应用程序的对象与其他对象之间的互相依赖关系。
1.1.1. 配置元数据
使用xml的配置
简单、直观 适合入门
基于注解的配置:
@Compont(@serivce @controller @repository) @Autowride
Spring 2.5 支持基于注解的元数据配置:
SSM框架开发中 的使用基于Java的配置: @Confiration @Bean @Import
从 Spring 3.0开始, 由Spring JavaConfig项目提供的功能已经成为Spring核
心框架的一部分。因此,你可以使用Java配置来代替 XML配置定义外部bean .
从spring4.0开始支持springboot1.0 之后
springboot 完全采用javaConfig的方式进行开发。
1.1.2. 容器的实例化
对象在Spring容器创建完成的时候就已经创建完成,不是需要用的时候才创建
1.1.3. 容器的使用
ApplicationContext是能够创建bean定义以及处理相互依赖关系的高级工厂接口,使用 方法T getBean(String name, Class<T> requiredType)获取容器实例。
1//创建spring上下文 加载所有的bean
2ApplicationContext context = new ClassPathXmlApplicationContext("service s.xml", "daos.xml");
3
4//获取bean
5PetStoreService service = context.getBean("petStore", PetStoreService.cla ss);
6
7//使用bean的对象
List<String> userList = service.getUsernameList();
1.2. bean的概述
1.2.1. 命名bean
<bean class="com.tuling.entity.User" id="user" name="user2 user3,user4;us er5"></bean>
为外部定义的bean起别名
1.2.2. 实例化Bean
1 使用构造器实例化 默认无需设置
缺点:无法干预实例化过程
2 使用静态工厂方法实例化
<bean class="com.tuling.service.impl.UserServiceImpl" id="userService2"factory‐method="createUserServiceInstance" ></bean>
public static UserServiceImpl createUserServiceInstance(){return new UserServiceImpl();}
使用实例工厂方法实例化
<bean class="com.tuling.service.impl.UserServiceImpl" id="userService"factory‐bean="serviceFactory"factory‐method="createUserService" ></bean>
public class createUserService{public UserServiceImpl createUserFactory(){return new UserServiceImpl();} }
1.3. 依赖
1.3.1. 依赖注入
基于setter方法的依赖注入
<!‐‐基于setter方法的依赖注入
.属性必须声明了set方法. name是根据set方法的名字来的 比如方法名字是: setIdxx ‐> name="idxx"‐‐>
<bean class="cn.tulingxueyuan.beans.User" id="user2">
<property name="idtuling" value="1"></property>
<property name="username" value="zhangsan"></property><property name="realname" value="张三"></property>
</bean>
基于构造函数的依赖注入
<!‐‐基于构造函数的依赖注入
.将会调用自定义构造函数来实例化对象,就不会调用默认的无参构造函数
. name是根据构造函数的参数名来的, 比如:User(String idxx) ‐> name="idxx"
. name属性可以省略 但是要注意参数的位置
.如果非要把位置错开 可以使用 name或者 index或者 type
. index是下标 从0开始
. type在位置错开情况下只能在类型不一样的时候指定才有明显效果
‐‐>
<bean class="cn.tulingxueyuan.beans.User" id="user3">
<constructor‐arg name="username" value="lisi"></constructor‐arg>
<constructor‐arg name="id_xushu" value="1"></constructor‐arg>
<constructor‐arg name="realname" value="李四"></constructor‐arg>
</bean>
使用p命名空间简化基于setter属性注入XML配置
使用c命名空间简化基于构造函数的XML
<!‐‐复杂数据类型‐‐>
<bean class="cn.tulingxueyuan.beans.Person" id="person" p:wife‐ ref="wife2">
<property name="id" value="1"></property>
<property name="realName" value=""></property>
<!‐‐设置null值‐‐>
<property name="name">
<null></null>
</property>
<!‐‐当依赖其他bean:内部bean inner bean
<property name="wife">
<bean class="cn.tulingxueyuan.beans.Wife" >
<property name="age" value="18"></property>
<property name="name" value="迪丽热巴"></property>
</bean>
</property>‐‐>
<!‐‐当依赖其他bean:引用外部bean
<property name="wife" ref="wife"></property>‐‐>
<property name="birthday" value="2020/05/20"></property>
<property name="hobbies">
<list>
<value>唱歌</value>
<value>跳舞</value>
<!‐‐如果List的泛型是比如:List<Wife> <bean>‐‐>
</list>
</property>
<property name="course" >
<map>
<entry key="1" value="JAVA"> </entry>
<entry key="2" value="HTML"> </entry>
</map>
</property>
</bean>
<!‐‐可以使用p命名空间来简化基于setter属性注入 它不支持集合‐‐>
<bean class="cn.tulingxueyuan.beans.Wife" id="wife" p:age="18" p:name="迪 丽热巴" ></bean>
<!‐‐可以使用c命名空间来简化基于构造函数属性注入 它不支持集合‐‐>
<bean class="cn.tulingxueyuan.beans.Wife" id="wife2" c:age="20" c:name="xxx"><!‐‐ <constructor‐arg name="age" value="18"></constructor‐arg>‐‐></bean>
1.3.2. 使用 属性
<!‐‐使用depends‐on可以设置先加载的Bean也就是控制bean的加载顺序‐‐>
<bean class="cn.tulingxueyuan.beans.Person" id="person" depends‐ on="wife"></bean>
<bean class="cn.tulingxueyuan.beans.Wife" id="wife"></bean>
1.3.3. 懒加载bean
<!‐‐使用lazy‐init设置懒加载
默认为false:在spring容器创建的时候加载(实例化)
true:在使用的时候(getBean)才会去加载(实例化)‐‐>
<bean class="cn.tulingxueyuan.beans.Person" id="person2" lazy‐ init="true">
<property name="id" value="1"></property>
<property name="realName" value="吴彦祖"></property>
<property name="name" value="徐庶"></property>
</bean>
1.3.4. 自动注入
当一个对象中需要引用另外一个对象的时候,在之前的配置中我们都是通过
property标签来进行手动配置的,其实在spring中还提供了一个非常强大的功能
就是自动装配,
可以按照我们指定的规则进行配置,配置的方式有以下几种:
default/no:不自动装配
byName:按照名字进行装配,以属性名作为id去容器中查找组件,进行赋
值,如果找不到则装配null
byType:按照类型进行装配,以属性的类型作为查找依据去容器中找到这个
组件,如果有多个类型相同的bean对象,那么会报异常,如果找不到则装配null
constructor:按照构造器进行装配,先按照有参构造器参数的类型进行装
配,没有就直接装配null;如果按照类型找到了多个,那么就使用参数名作为
id继续匹配,找到就装配,找不到就装配null
通过将autowire-candidate 属性设置为false,避免对bean定义进行自动装
配,如下一节所述。
通过将其<bean/> 元素的primary属性设置为 true,将单个bean定义指定为主要
候选项。
<!‐‐**************************************基于xml自动注入 begin*********** ***************************************‐‐>
<!‐‐自动注入:
1. bytype根据类型自动注入(spring会根据bean里面的所有对象属性的类型,只要它匹配到bean里面某一个类型跟属性类型吻合就会自动注入
2. byname会根据属性setxxx的名字来自动匹配 (spring会根据bean里面的所有对象属性的set的名字,只要它匹配到bean里面某一个名字跟属性名字吻合就会自动注入
3. constructor优先根据名字来找, 如果名字没有匹配到根据类型来匹配, 如果类型匹
配到多个则不会自动注入
注意:
bytype如果匹配到两个同样的类型会出现错误,所以一定要保证ioc容器里面只有一个对应类型的bean
byname最能匹配到唯一的那个bean
constructor保证构造函数不能包含多余的其他参数
default:不会进行自动注入
<bean class="cn.tulingxueyuan.beans.Person" id="person6" autowire="const ructor" >
<property name="id" value="1"></property>
<property name="realName" value="吴彦祖"></property>
<property name="name" value="徐庶"></property>
</bean>
<bean class="cn.tulingxueyuan.beans.Wife" id="wife" p:age="18" p:name="小鑫科技" ></bean>
<bean class="cn.tulingxueyuan.beans.Wife" id="QBL" p:age="60" p:name="小鑫科技1号" ></bean>
**************************************基于xml自动注入 end*************** ***********************************‐‐>
1.4. Bean 的作用域
1.4.1. Singleton(单例)的作用域
1.4.2.Prototype(原型)的作用域
<!‐‐作用域scope
singleton默认:单例 只会在Ioc容器种创建一次
prototype多例(原型bean)每次获取都会new一次新的bean‐‐>
<bean class="cn.tulingxueyuan.beans.Person" id="person3" scope="prototype">
<property name="id" value="1"></property>
<property name="realName" value="吴彦祖"></property><property name="name" value="徐庶"></property>
</bean>
1.5. 自定义bean的特性
1.5.1. 生命周期回调
1.5.2初始化方法回调销毁方法回调
1.5.3在非Web应用中优雅地关闭Spring IoC容器
/**
*生命周期回调
* 1.使用接口实现的方式来实现生命周期的回调:
* 1.1初始化方法: 实现接口: InitializingBean重写afterPropertiesSet方法 初始化会自动调用的方法
* 1.1销毁的方法: 实现接口: DisposableBean重写destroy方法 销毁的时候自动
调用方法
*什么时候销毁:在spring容器关闭的时候 close()
*或者 使用ConfigurableApplicationContext.registerShutdownHook方法优雅的关闭
*
* 2.使用指定具体方法的方式实现生命周期的回调:
* 在对应的bean里面创建对应的两个方法
* init‐method="init" destroy‐method="destroy"
*/
1.6 ApplicationContextAware 和 BeanNameAware
1.7. Bean 定义的继承
<!‐‐bean的继承 一个bean继承另一个bean 可以使用parent属性指定父类bean 如果想让父类bean不能被实例化 abstract="true"
<bean class="cn.tulingxueyuan.beans.Person" id="person4" abstract="true">
<property name="id" value="1"></property>
<property name="realName" value="吴彦祖"></property>
<property name="name" value="徐庶"></property>
</bean>
<bean class="cn.tulingxueyuan.beans.Person" id="person5" parent="person4" >
<property name="realName" value="刘德华"></property>
</bean>‐‐>
spring创建第三方bean对象 在Spring中,很多对象都是单实例的,在日常的开发中,我们经常需 要使用某些外部的单实例对象,例如数据库连接池,下面我们来讲解下如何在 spring中创建第三方bean实例。 1、导入数据库连接池的pom文件
1、导入数据库连接池的pom文件
<!‐‐ https://mvnrepository.com/artifact/com.alibaba/druid ‐‐>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.21</version>
</dependency>
<!‐‐ https://mvnrepository.com/artifact/mysql/mysql‐connector‐j
ava ‐‐>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql‐connector‐java</artifactId>
<version>5.1.47</version>
</dependency>
2、编写配置文件 ioc.xml
<?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 htt p://www.springframework.org/schema/beans/spring‐beans.xsd">
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="username" value="root"></property>
<property name="password" value="123456"></property>
<property name="url" value="jdbc:mysql://localhost:3306/demo"></pr operty>
<property name="driverClassName" value="com.mysql.jdbc.Driver"> </property>
</bean>
</beans>
3、编写测试文件
public class MyTest {
public static void main(String[] args) throws SQLException {
ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
DruidDataSource dataSource = context.getBean("dataSource", DruidDa taSource.class);
System.out.println(dataSource);
System.out.println(dataSource.getConnection());
}
}