Spring IOC控制反转
什么是控制反转
IOC(Inverse Of Control)控制反转,即,把创建对象的权利交给框架。
也就是指将对象的创建、对象的存储、对象的管理交给了spring容器。
(spring容器是spring中的一个核心模块,用于管理对象,底层可以理解为是一个map集合)
在此之前,当需要对象时,通常是利用new关键字创建一个对象:
private EmpService service = new EmpServiceImpl();
但由于new对象,会提高类和类之间的依赖关系,即代码之间的耦合性。
而现在我们可以将对象的创建交给框架来做:
private EmpService service = (EmpService)BeanFactory.getBean("EmpService");
Spring jar包
<dependencies>
<!-- 添加junit的jar包 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
</dependency>
<!-- 添加spring的jar包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.1.3.RELEASE</version>
</dependency>
</dependencies>
applicationContext.xml配置文件
配置文件的名字一般用applicationContext.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
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 将EmpService的实现类, 声明到spring容器中, 由spring容器创建该类的实例 -->
<bean id="userServiceImpl" class="com.test.service.UserServiceImpl"/>
</beans>
获取对象操作
@Test
public void testIOC() {
// 1. 获取srping容器对象( 传入spring配置文件的路径 )
AbstractApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
// 2. 通过spring容器获取EmpService接口的子类对象实例
EmpService service = (EmpService) ac.getBean("empService");
System.out.println(service);
EmpDao empDao = ac.getBean("empDap", EmpDao.class);
System.out.println(empDao);
}
Bean标签
bean标签主要作用就是把对象注入IOC容器, 在程序启动时会初始化IOC里的所有对象
class属性
值为bean的全类名(包名+类名)
用来指定要注入到IOC容器的java Bean对象
id属性
值为bean的唯一标志, 即bean的名字, 获取bean对象就是根据名字获取
指定一个bean的名字, id不能重复, 可以省略, 如果省略, id的默认值为class中指定Bean对象的类名(没有包名)且首字母小写
name属性
功能和id属性一样。id属性值不能包含特殊符号,但是name属性中可以包含特殊符号。(一般不用name属性)
scope属性
用于指定bean的单例, 多例等
属性的取值有5种, 不能为娶她值
- singleton 表示在spring容器中的单例,通过spring容器获得该bean时总是返回唯一的实例
- prototype表示多例, 每次获得bean都会生成一个新的对象
- request表示在一次http请求内有效(只适用于web应用)
- session表示在一个用户会话内有效(只适用于web应用)
- globalSession表示在全局会话内有效(只适用于web应用)
autowire属性
autowire表示bean的自动装配,即自动完成依赖的注入, autowire的值有:
- no : 默认值,不进行自动装配
- byName : 根据属性名自动装配。此选项将检查容器并根据名字查找与属性完全一致的bean,并将其与属性自动装配
- byType : 如果容器中存在一个与指定属性类型相同的bean,那么将与该属性自动装配;如果存在多个该类型bean,那么抛出异常,并指出不能使用byType方式进行自动装配;如果没有找到相匹配的bean,则什么事都不发生,也可以通过设置dependency-check="objects" 让Spring抛出异常。
- constructor:与byType方式类似,不同之处在于它应用于构造器参数。如果容器中没有找到与构造器参数类型一致的bean, 那么抛出异常
- autodetect : 通过bean类的内省机制(introspection)来决定是使用constructor还是byType方式进行自动装配。如果发现默认的构造器,那么将使用byType方式,否则采用 constructor。
- default:由上级标签的default-autowire属性确定。
init-method和destory-method属性
指定Bean中的初始化方法和销毁方法
-
init-method属性是bean的初始方法,在创建好bean后调用该方法。
-
destory-method属性是bean的销毁方法,在销毁bean之前调用该方法,一般在该方法中释放资源
factory-method属性
factory-method工厂方法属性,通过该属性,我们可以调用一个指定的静态工厂方法,创建bean实例。
例如:
public class BeanAttribute {
//... 类属性及方法等
/**
* 静态工厂方法生成user对象
* @return
*/
public static User createUser() {
return new User();
}
}
applicationContext.xml
<bean id="userFactory" class="com.text.factory.BeanAttribute" factory-method="createUser"></bean>
测试
public static void main(String[] args) {
ApplicationContext act = new ClassPathXmlApplicationContext("applicationContext.xml
User user = (User) act.getBean("userFactory");
System.out.println(user);
}
上述代码相当于:
User user = BeanAttribute.createUser();
factory-bean属性
factory-bean就是生成bean的工厂对象,factory-bean属性和factory-method属性一起使用,首先要创建生成bean的工厂类和方法。
public class UserFactory {
public User createUser() {
return new User();
}
}
上面这段代码就是生产user对象的工程方法了,我们要创建user对象,在java代码中我们这样写:
UserFactory userFactory = new UserFactory();
User user = userFactory.createUser();
在Spring中我们怎么写?
首先在XML配置中配置UserFactory类和User类:
<bean id="userFactory" class="com.test.UserFactory"></bean>
<bean id="user" factory-bean="userFactory" factory-method="createUser"></bean
然后getBean获取User对象
ApplicationContext act = new ClassPathXmlApplicationContext("applicationContext.xml");
User user = (User) act.getBean("user");
System.out.println(user);