您的位置:首页 > 移动开发

spring中多例、BeanFactoryAware、ApplicationContextAware、InitializingBean接口

2015-11-26 22:29 423 查看
在web项目开发中,有时需要对IOC过程做定制化,则应用以下接口。

动态代理

InitializingBean接口

参考

1:spring为bean提供了两种初始化bean的方式,实现InitializingBean接口,实现afterPropertiesSet方法,或者在配置文件中同过init-method指定,两种方式可以同时使用

2:实现InitializingBean接口是直接调用afterPropertiesSet方法,比通过反射调用init-method指定的方法效率相对来说要高点。但是init-method方式消除了对spring的依赖

3:如果调用afterPropertiesSet方法时出错,则不调用init-method指定的方法。

4:TransactionTemplate实现InitializingBean接口,主要是判断transactionManager是否已经初始化,如果没有则抛出异常。源码如下:

public void afterPropertiesSet() {

if (this.transactionManager == null) {

throw new IllegalArgumentException("Property 'transactionManager' is required");

}

}


ApplicationContextAware接口。

这里要明白单多例模式的设置是在scope设置,不然默认是单例

这个项目中使用是因为rest用Jersey来搭建,其controller可以不用Spring管理,所以用这个接口在使用时传入beanName加载

public class BeanFactory implements ApplicationContextAware {
public static ApplicationContext context;
@Override
public void setApplicationContext(ApplicationContext context)
throws BeansException {
BeanFactory.context = context;
}
@SuppressWarnings("unchecked")
public static <T> T getBean(String beanName) {
return (T) context.getBean(beanName);
}

}


如何在单例中调用多例对象

Spring注入非单例bean以及scope的作用范围

加载Spring配置文件时,如果Spring配置文件中所定义的Bean类实现了ApplicationContextAware 接口,那么在加载Spring配置文件时,会自动调用ApplicationContextAware 接口中的setApplicationContext方法,获得ApplicationContext对象。为啥?

在大部分情况下,容器中的bean都是singleton类型的。如果一个singleton bean要引用另外一个singleton bean,或者一个非singleton bean要引用另外一个非singleton bean时,通常情况下将一个bean定义为另一个bean的property值就可以了。不过对于具有不同生命周期的bean来说这样做就会有问题了,比如在调用一个singleton类型bean A的某个方法时,需要引用另一个非singleton(prototype)类型的bean B,对于bean A来说,容器只会创建一次,这样就没法在需要的时候每次让容器为bean A提供一个新的的bean B实例。

通过这样可以获得spring的context,进一步获得想要的bean

FactoryBean接口

参考

有getBean的方法,这样就可以调用它生成新对象了

BeanFactory 以Factory结尾,它是一个工厂类,用于管理Bean的一个工厂

FactoryBean:以Bean结尾,表示它是一个Bean,不同于普通Bean的是:它是实现了FactoryBean接口的Bean,根据该Bean的Id从BeanFactory中获取的实际上是FactoryBean的getObject()返回的对象,而不是FactoryBean本身, 如果要获取FactoryBean对象,可以在id前面加一个&符号来获取。自此就返回了代理类

自此一个手动拦截器如下:

1. 自定义注解@Interceptor在需要被拦截的类上写上需要哪些拦截器检查。拦截器接口可以有doBefore,doAfter。在其中解析其注解,得到要用到的类。

2. proxy类,继承ApplicationContextAware,FactoryBean接口。在这里面处理注解,并生成代理对象的目标对象,用一个动态代理包上其中的代理对象设置为真正使用的bean。

3. 使用时候用动态代理的proxy类。

BeanFactoryAware

参考

private BeanFactory beanFactory;
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
}
//这样我们就可以直接拿东西用了,如
Object  object = beanFactory.getBean(beanName);


我们既然可以通过set来拿到我们要的对象,为什么还要用这个beanFactory呢,道理很简单,因为有些情况是需要动态的去获取对象的,比如说我有10个银行的处理对象,他们都继承了我的BankService对象,但是具体处理的时候要哪家银行的对象呢?这个依赖于用户的选择。你可以注入10个BankService实例,然后用if –else来搞,不过那样太坨了。每增加一家银行你都需要改代码。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: