2.Sping与IoC-Bean的装配

将由程序代码直接操控的对象调用权交由容器,通过容器来装配管理对象。

IoC的实现方式:

  • 依赖查找 Dependency Lookup/DL:容器提供回调接口和上下文环境给组件,程序代码则需要提供具体的查找方法。
  • 依赖注入 Dependency Injection/DI:程序代码不做定位查询,这些工作由容器自行完成。依赖注入式程序运行过程中,若需要调用另一个对象协助时,无须在代码中创建被调用者,而是依赖于外部容器,由外部容器创建后传递给程序

依赖注入是目前最优秀的解耦方式,依赖注入让Spring的Bean之间以配置文件的方式组织在一起,而不是以硬编码的方式耦合在一起。


ApplicationContext与BeanFactory容器的区别:

这两个容器对其中Bean的创建时机不同:

  1. ApplicationContext容器在进行初始化时,会将其中的所有Bean(对象)进行创建;
    缺点:占用系统资源(内存、cpu等)
    优点:响应速度快
  2. BeanFactory容器中的对象,在容器初始化时并不会被创建,而是在真正获取该对象时才被创建;
    缺点:相对来说,响应速度慢
    有点:不多占用系统资源

一般情况下使用ApplicationContext,响应速度快,提高体验


Bean的装匹配

Bean的装配,即Bean对象的创建。容器根据代码需求创建Bean对象后再传递给代码的过程,称为Bean的装配

默认装配方式

代码通过getBean()方式从容器获取指定的Bean实例,容器首先会调用Bean类的无参构造器,创建空值的实例对象

动态工厂Bean

有时,项目中需要通过工厂类来创建Bean实例,而不能像前面一样,直接由Spring容器来装配Bean实例。使用工厂模式创建Bean实例,就会使工厂类与要创建的Bean类耦合在一起。

  1. 将动态工厂Bean作为普通Bean使用
    将动态工厂Bean作为普通Bean来使用是指,在配置文件中注册过动态工厂Bean后,测试类直接通过getBean()获取到工厂对象,再由工厂对象调用其相应方法创建相应的目标对象。配置文件中无需注册目标对象的Bean。因为目标对象的创建不由Spring容器类管理。

工厂类

public class ServiceFactory {
    public ISomeService getSomeService() {
        return new SomeServiceImpl();
    }
}

ISomeService.java

public interface ISomeService {
    void doSome();
}

SomeServiceImpl.java

public class SomeServiceImpl implements ISomeService {

    @Override
    public void doSome() {
        System.out.println("执行doSome()方法");
    }
}

applicationContext.xml配置文件

	<!--注册动态工厂-->
    <bean id="factory" class="com.chen.service.ServiceFactory"/>
    <!--注册service:动态工厂Bean-->
    <bean id="myService" factory-bean="factory" factory-method="getSomeService"/>
</beans>

测试

	@Test
    public void testFactory() {
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
        ISomeService service = (ISomeService)ac.getBean("myService");
        service.doSome();
    }

静态工厂Bean

applicationContext.xml配置文件

<!--注册Service:静态工厂Bean-->
<bean id="myService" class="com.chen.service.ServiceFactory" factory-method="getSomeService"/>

测试

	@Test
	public void testStaticFactory(){
		ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
		ISomeService service = (ISomeService)ac.getBean("myService");
		service.doSome();
	}



Bean作用域
<!--注册service,
	scope="prototype" 原型模式,其对象的创建时机不是在Spring容器初始化时创建,而是在代码中真正访问时才创建
	scope="singleton" 单例模式,其对象的创建时机是在Spring容器初始化时创建,是默认值
-->
<bean id="myService" class="com.chen.service.SomeServiceImpl" scope="singleton"/>

Bean后处理器

特殊的Bean,容器中所有的Bean在初始化时,均会自动执行该类的两个方法。由于该Bean是由其它Bean自动调用执行,不是程序员手工调用,故此Bean无须id属性

在Bean后处理器类方法中,只要对Bean类与Bean类中的方法进行判断,就可实现对指定的Bean的指定方法进行功能扩展与增强。方法返回的Bean对象,即是增过的对象

代码中需要自定义Bean后处理器类,该类就是实现了接口BeanPostProcessor的类。该接口中包含两个方法,分别在目标Bean初始化完毕之前与之后执行。他们的返回值为:功能被扩展或增强后的Bean对象。

bean初始化完毕的标志:一个方法将被执行。即当该方法被执行时,表示该Bean被初始化完毕。所以Bean后处理器重两个方法的执行,是在这个方法之前之后执行。这个方法在后面将会讲到。

/*
第一参数是系统即将初始化的Bean实例,第二个参数是该Bean实例的id属性值。若Bean没有id就是name属性值
*/

//该方法会在目标Bean初始化完毕之前由容器自动调用
public Object postProcessBeforeInitialization(Object bean, String beanId) throw BeansException

//该方法会在目标Bean初始化完毕之后由容器自动调用
public Object postProcessAfterInitialization(Object bean, String beanId) throw BeansException

定制Bean的生命始末

为Bean定制初始化后的生命行为,也可以为Bean定制销毁前的生命行为。这些方法需要在Bean类中事先定义好,是方法名随意的public void 方法。

对于销毁方法的执行,需要有两个条件:

  1. 当前Bean需要时singleton的
  2. 要手工关闭容器
//手工关闭容器示例
ApplicationContext ac = new ClassPathXmlApplicationContext(resource);
((ClassPathXmlApplicationContext)ac).close();

Bean的生命周期

仅作了解,有大概的映像就行

  1. 执行无参构造器
  2. 执行setter
  3. 获取到bean的id=myService
  4. 获取到BeanFactory容器
  5. 执行before()方法
  6. Bean初始化完毕了
  7. 初始化完毕之后
  8. 执行after()方法
  9. 执行业务方法
  10. 实现接口的销毁之前
  11. 销毁之前

id与name属性

简记:name和id是一样的

一般情况下,命名<bean/>使用id属性,而不使用name属性。在没有id属性的情况下,name属
性与id属性作用是相同的。但当<bean/>中含有一些特殊字符时,就需要使用name属性了。

id的命名需要满足XML对id属性命名规范:必须以字母开头,可以包含字母、数字、下划线、连字符、句号、冒号

name属性值则可以包含各种字符

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值