通过Spring提供的接口,改变Spring对Bean的初始化行为

Spring对开闭原则的体现,提供了大量的回调接口,例如BeanPostProcess,该接口的作用是我们可以添加自己的逻辑来控制Bean的初始化构建行为,如我们不想返回Bean本身而是需要返回他的代理对象,修改所依赖的属性对象等等。
下图是BeanPostProcess的关系结构图:
[img]
[img]http://dl2.iteye.com/upload/attachment/0098/0741/e4c7e96d-4a9a-3c6f-989a-9c158502acfc.png[/img]
[/img]
InstantiationAwareBeanPostProcessor 该接口非常重要,在Spring的Aop自动代理的实现中就需要使用该接口,原因很简单,我们的织入我们需要的我们的一些列的逻辑到目标中,所以我们返回的应该目标对象的代理对象。

public abstract class AbstractAutoProxyCreator extends ProxyConfig
implements SmartInstantiationAwareBeanPostProcessor, BeanClassLoaderAware, BeanFactoryAware,
Ordered, AopInfrastructureBean {

.............................................................
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
Object cacheKey = getCacheKey(beanClass, beanName);

if (!this.targetSourcedBeans.contains(cacheKey)) {
if (this.advisedBeans.contains(cacheKey) || this.nonAdvisedBeans.contains(cacheKey)) {
return null;
}
if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
this.nonAdvisedBeans.add(cacheKey);
return null;
}
}

// Create proxy here if we have a custom TargetSource.
// Suppresses unnecessary default instantiation of the target bean:
// The TargetSource will handle target instances in a custom fashion.
//获取目标源
TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
if (targetSource != null) {
this.targetSourcedBeans.add(beanName);
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
//重点看这句,创建代理对象,通过ProxyFactory(aop的代码编程方式)
Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
this.proxyTypes.put(cacheKey, proxy.getClass());
//然后返回代理对象
return proxy;
}

return null;
}


}





以InstantiationAwareBeanPostProcessor为例(其他的都一样类似)

public class InstantiationAwareBeanPostProcessorImp implements
InstantiationAwareBeanPostProcessor {

@Override
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
System.out.println("postProcessBeforeInitialization" + bean
+ " beanName:" + beanName);

return bean;
}

@Override
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
// TODO Auto-generated method stub
return bean;
}

/**
*
*/
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass,
String beanName) throws BeansException {

System.out.println("postProcessBeforeInstantiation(class)" + beanClass
+ " beanName:" + beanName);

//此处修改了Bean本身所需要的实例对象,阻断了Spring的创建Bean执行流 程

return new InstantiationAwareBeanPostProcessorImp();
}

@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName)
throws BeansException {
// TODO Auto-generated method stub
return false;
}

@Override
public PropertyValues postProcessPropertyValues(PropertyValues pvs,
PropertyDescriptor[] pds, Object bean, String beanName)
throws BeansException {
System.out.println("postProcessPropertyValues");
return null;
}

}



当Spring在执行创建Bean的时候,会先去执行InstantiationAwareBeanPostProcessor 该接口里面的postProcessBeforeInstantiation如果返回的不是null则调用BeanPostProcessor.postProcessAfterInitialization方法,如上例我们修改了bean本省应该返回的实例,只要这2个方法不返回NULL,Spring就会停止后面的Bean的创建,直接返回该实例(return new InstantiationAwareBeanPostProcessorImp())


@Override
protected Object createBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
throws BeanCreationException {

if (logger.isDebugEnabled()) {
logger.debug("Creating instance of bean '" + beanName + "'");
}
// Make sure bean class is actually resolved at this point.
resolveBeanClass(mbd, beanName);

// Prepare method overrides.
try {
mbd.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbd.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}

try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
//在这里执行InstantiationAwareBeanPostProcessor里面的方法,
// 如果返回值不为NULL直接退出
Object bean = resolveBeforeInstantiation(beanName, mbd);
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
//否则去执行后续的创建过程
Object beanInstance = doCreateBean(beanName, mbd, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值