IOC、DI
IOC容器:控制反转。通常实例化一个类的对象,我们都会用new关键字来实例化。而“控制反转”将对象实例化的这一操作从程序员手动完成转交给IOC容器完成。
DI(依赖注入Dependency injection):容器创建完对象后,处理对象与对象之间的依赖关系。
依赖注入的几种方式:
- 设值注入
- 构造器注入
设值注入:
类文件
public class InjectionService implements InjectionServiceImpl {
private InjectionDAO injectionDAO;
/**设值注入
* @param injectionDAO 要设置的 injectionDAO
*/
public void setInjectionDAO(InjectionDAO injectionDAO) {
this.injectionDAO = injectionDAO;
}
public void GetServer(String meg) {
meg = meg + ".server";
injectionDAO.save(meg);
}
}
xml文件
<!-- 设值注入 -->
<bean id="InjectionService" class="com.InjectionService">
<property name="InjectionDAO" ref="InjectionDAO"></property>
</bean>
<bean id="InjectionDAO" class="com.InjectionDAO">
</bean>
name:InjectionService类里面的名叫InjectionDAO的属性,ref:引用了InjectionDAO这个对象.
表达的含义就是将InjectionDAO对象作为InjectionService的属性注入到InjectionService对象中.
构造器注入:
类文件
public class InjectionService implements InjectionServiceImpl {
/**
* 构造器注入
* @param injectionDAO
*/
public InjectionService(InjectionDAO injectionDAO)
{
this.injectionDAO = injectionDAO;
}
public void GetServer(String meg) {
meg = meg + ".server";
injectionDAO.save(meg);
}
}
xml文件
<!-- 设值注入 -->
<bean id="InjectionService" class="com.InjectionService">
<constructor-arg name="injectionDAO" ref="InjectionDAO"></constructor-arg>
</bean>
<bean id="InjectionDAO" class="com.InjectionDAO">
</bean>
可以把bean看作对象的代言,constructor-arg表示调用InjectionService对象的构造函数,参数名是injectionDAO,值为对InjectionDAO对象的引用.
上面两种依赖方式建立了对象与对象之间的关系。
Bean
Bean的配置项
- Id
- Class
- Scope
- Constructor arguments
- Properties
- Autowiring mode
- lazy-initialization mode
- Initialization/destruction method
Bean的作用域
singleton:单例,指一个Bean容器中只存在一份
prototype:每次请求(每次使用)创建新的实例,destroy方式不生效
request:每次http请求创建一个实例且仅在当前request内有效
session:同上,每次http请求创建,当前session内有效
global session:基于portlet的web中有效(portlet定义了global session),如果是在web中,和session的效果一样.
<bean id="coarp" class="contsort.coarp" scope="prototype"></bean>
@RunWith(BlockJUnit4ClassRunner.class)
public class TestOne extends UnitTestBase {
public TestOne()
{
super("classpath*:spring-cont.xml");
}
@Test
public void TestMain()
{
coarp coarps = super.getBean("coarp");
coarp coarps2 = super.getBean("coarp");
System.out.println("coarps和coarps2是一样的:"+coarps.equals(coarps2));
}
}
<bean id="coarp" class="contsort.coarp" scope="singleton"></bean>
@RunWith(BlockJUnit4ClassRunner.class)
public class TestOne extends UnitTestBase {
public TestOne()
{
super("classpath*:spring-cont.xml");
}
@Test
public void TestMain()
{
coarp coarps = super.getBean("coarp");
coarp coarps2 = super.getBean("coarp");
System.out.println("coarps和coarps2是一样的:"+coarps.equals(coarps2));
}
}
Bean的生命周期
初始化
销毁
初始化和销毁有三种实现方式:
- 实现接口:在类中实现org.springframework.beans.factory.InitializingBean接口并覆盖afterPropertiesSet方法、实现org.springframework.beans.factory.DisposableBean接口并覆盖destroy方法。(单个bean)
- 单属性配置:在xml文件中配置init-method、destroy-method属性,属性值是类中的方法名。(单个bean)
- 全局属性配置:在xml文件中全局配置default-init-method、default-destroy-method属性,属性值是方法名。(所有bean)
实现接口的方式
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
/**
* 验证Bean的生命周期
* @author jinlong chen
*
*/
public class coarp implements InitializingBean,DisposableBean {
public void say()
{
System.out.println("调用了coarp的say方法");
}
/**
* 销毁时执行的方法
*/
@Override
public void destroy() throws Exception {
// TODO 自动生成的方法存根
System.out.println("通过实现接口的方式销毁了");
}
/**
* 初始化执行的方法
*/
@Override
public void afterPropertiesSet() throws Exception {
// TODO 自动生成的方法存根
System.out.println("通过实现接口的方式初始化了");
}
}
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.BlockJUnit4ClassRunner;
import imooc.UnitTestBase;
/**
* 测试类
* @author jinlong chen
*
*/
@RunWith(BlockJUnit4ClassRunner.class)
public class TestOne extends UnitTestBase {
public TestOne()
{
super("classpath*:spring-cont.xml");
}
@Test
public void TestMain()
{
super.getBean("Story");
super.getBean("coarp");
}
}
输出结果
绑定属性的方法(单个bean)
<bean id="coarp" class="contsort.coarp" init-method="start" destroy-method="stop"></bean>
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
/**
* 验证Bean的作用域
* @author jinlong chen
*
*/
public class coarp {
public void say()
{
System.out.println("调用了coarp的say方法");
}
protected void start() {
System.out.println("通过与属性绑定的方法初始化");
}
protected void stop() {
System.out.println("通过与属性绑定的方法销毁");
}
}
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.BlockJUnit4ClassRunner;
import imooc.UnitTestBase;
/**
* 测试类
* @author jinlong chen
*
*/
@RunWith(BlockJUnit4ClassRunner.class)
public class TestOne extends UnitTestBase {
public TestOne()
{
super("classpath*:spring-cont.xml");
}
@Test
public void TestMain()
{
super.getBean("coarp");
}
}
输出结果
全局配置和单个配置类似
<?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" default-init-method="start" default-destroy-method="stop">
<bean id="coarp" class="contsort.coarp"></bean>
</beans>
其他的都是一样的。
当属性绑定的方式和实现接口两者同时存在时,这两个方法都会执行,优先执行实现接口的方法。