代理的提前生成是在实例化的过程中,进入创建Bean的方法createBean():
所属类:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
if (logger.isTraceEnabled()) {
logger.trace("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
// Make sure bean class is actually resolved at this point, and
// clone the bean definition in case of a dynamically resolved Class
// which cannot be stored in the shared merged bean definition.
// 马上就要实例化Bean了,确保beanClass已被加载
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// Prepare method overrides.
try {
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
// 实例化前
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
try {
// 实例化(主要看这个)*****
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isTraceEnabled()) {
logger.trace("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
// A previously detected exception with proper bean creation context already,
// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}
在实例化前会执行resolveBeforeInstantiation(beanName, mbdToUse)方法,有可能会返回代理(而不是目标bean实例),进入resolveBeforeInstantiation():
所属类:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// Make sure bean class is actually resolved at this point.
// Synthetic表示合成,如果某些Bean是合成的,则不会经过BeanPostProcessor的处理
// hasInstantiationAwareBeanPostProcessors()方法判断spring中有无InstantiationAwareBeanPostProcessor接口类型的
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
// 实例化之前执行的方法
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
// 获取到实例,直接执行实例化之后的方法
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
先执行applyBeanPostProcessorsBeforeInstantiation(),
所属类:本类
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
if (result != null) {
return result;
}
}
}
return null;
}
调用到AbstractAutoProxyCreator.postProcessBeforeInstantiation(),如果我们有自定义TargetSource,就在这里创建代理:
所属类:org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
Object cacheKey = getCacheKey(beanClass, beanName);
if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
if (this.advisedBeans.containsKey(cacheKey)) {
return null;
}
if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
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 targetSource = getCustomTargetSource(beanClass, beanName);
if (targetSource != null) {
if (StringUtils.hasLength(beanName)) {
this.targetSourcedBeans.add(beanName);
}
// 检查当前Bean是否有切面
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
// 创建代理
Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
return null;
}
在这个方法中,找切面和生成代理的代码和之前的一样,唯一不同的地方就是getCustomTargetSource(beanClass, beanName)方法,
所属类:org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator
protected TargetSource getCustomTargetSource(Class<?> beanClass, String beanName) {
// We can't create fancy target sources for directly registered singletons.
// 如果自定义的TargetSource不为空,就会调用到父类AbstractBeanFactoryBasedTargetSourceCreator的getTargetSource(beanClass, beanName)方法
if (this.customTargetSourceCreators != null &&
this.beanFactory != null && this.beanFactory.containsBean(beanName)) {
for (TargetSourceCreator tsc : this.customTargetSourceCreators) {
TargetSource ts = tsc.getTargetSource(beanClass, beanName);
if (ts != null) {
// Found a matching TargetSource.
if (logger.isTraceEnabled()) {
logger.trace("TargetSourceCreator [" + tsc +
"] found custom TargetSource for bean with name '" + beanName + "'");
}
return ts;
}
}
}
// No custom TargetSource found.
return null;
}
我们看一下this.customTargetSourceCreators,它是TargetSourceCreator的数组:
private TargetSourceCreator[] customTargetSourceCreators;
public void setCustomTargetSourceCreators(TargetSourceCreator... targetSourceCreators) {
this.customTargetSourceCreators = targetSourceCreators;
}
自定义TargetSourceCreator,为了方便,通过继承AbstractBeanFactoryBasedTargetSourceCreator创建了自定义的TargetSource类:
@Component
public class CustomTargetSourceCreator extends AbstractBeanFactoryBasedTargetSourceCreator {
@Override
protected AbstractBeanFactoryBasedTargetSource createBeanFactoryBasedTargetSource(Class<?> beanClass, String beanName) {
if (getBeanFactory() instanceof ConfigurableListableBeanFactory) {
if(beanClass.isAssignableFrom(StudentServiceImpl.class)) {
return new CustomTargetSource();
}
}
return null;
}
}
实现BeanPostProcessor接口,在postProcessAfterInitialization()方法中将上面自定义的TargetSourceCreator设置进去,这样,我们代理入口类的实例就会有TargetSourceCreator实例。
@Component
public class SetCustomTargetSourceCreator implements BeanPostProcessor, PriorityOrdered, BeanFactoryAware {
private BeanFactory beanFactory;
@Override
public int getOrder() {
return 45;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if(bean instanceof AnnotationAwareAspectJAutoProxyCreator) {
AnnotationAwareAspectJAutoProxyCreator annotationAwareAspectJAutoProxyCreator = (AnnotationAwareAspectJAutoProxyCreator)bean;
CustomTargetSourceCreator customTargetSourceCreator = new CustomTargetSourceCreator();
customTargetSourceCreator.setBeanFactory(beanFactory);
// 将上面自定义的TargetSourceCreator设置进去
annotationAwareAspectJAutoProxyCreator.setCustomTargetSourceCreators(customTargetSourceCreator);
}
return bean;
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
}
}
自定义TargetSource类,继承AbstractBeanFactoryBasedTargetSource:
public class CustomTargetSource extends AbstractBeanFactoryBasedTargetSource {
@Override
public Object getTarget() {
// getBean()实例化,在这里才会生成被代理类的实例(是目标对象,而不是代理对象)
return getBeanFactory().getBean(getTargetBeanName());
}
}
AbstractBeanFactoryBasedTargetSourceCreator 作用是提前生成代理,并将目标对象变成多例,并将自定义的TargetSource类返回。
public final TargetSource getTargetSource(Class<?> beanClass, String beanName) {
// 创建TargetSource对象
AbstractBeanFactoryBasedTargetSource targetSource =
createBeanFactoryBasedTargetSource(beanClass, beanName);
if (targetSource == null) {
return null;
}
if (logger.isDebugEnabled()) {
logger.debug("Configuring AbstractBeanFactoryBasedTargetSource: " + targetSource);
}
// 生成新的BeanFactory实例
DefaultListableBeanFactory internalBeanFactory = getInternalBeanFactoryForBean(beanName);
// We need to override just this bean definition, as it may reference other beans
// and we're happy to take the parent's definition for those.
// Always use prototype scope if demanded.
// 从之前旧的BeanFactory中取出BeanDefinition,并生成新的BeanDefinition
BeanDefinition bd = this.beanFactory.getMergedBeanDefinition(beanName);
GenericBeanDefinition bdCopy = new GenericBeanDefinition(bd);
if (isPrototypeBased()) {
// 变成原型的
bdCopy.setScope(BeanDefinition.SCOPE_PROTOTYPE);
}
// 将合并后的BeanDefinition注册到新的BeanFactory
internalBeanFactory.registerBeanDefinition(beanName, bdCopy);
// Complete configuring the PrototypeTargetSource.
// 完成TargetSource的配置(TargetBeanName和BeanFactory)
targetSource.setTargetBeanName(beanName);
targetSource.setBeanFactory(internalBeanFactory);
return targetSource;
}
回到postProcessBeforeInstantiation()方法中,得到的TargetSource就是自定义的TargetSource,然后执行createProxy()方法生成JdkDynamicAopProxy的代理实例,执行invoke()方法时调用到了自定义的CustomTargetSource类的getTarget(),在这里才生成了被代理类的实例。
但需要注意的是,这里虽然是调用了BeanFactory.getBean()方法,后面也生成了代理,但返回的却是目标对象(原始对象),为什么?
通过源码可以看出,把旧的传进去,生成了一个新的BeanFactory(DefaultListableBeanFactory ):
所属类:aop.framework.autoproxy.target.AbstractBeanFactoryBasedTargetSourceCreator
protected DefaultListableBeanFactory getInternalBeanFactoryForBean(String beanName) {
synchronized (this.internalBeanFactories) {
DefaultListableBeanFactory internalBeanFactory = this.internalBeanFactories.get(beanName);
if (internalBeanFactory == null) {
internalBeanFactory = buildInternalBeanFactory(this.beanFactory);
this.internalBeanFactories.put(beanName, internalBeanFactory);
}
return internalBeanFactory;
}
}
接着看buildInternalBeanFactory()方法,会过滤掉支持AOP功能的入口类:AnnotationAwareAspectJAutoProxyCreator
protected DefaultListableBeanFactory buildInternalBeanFactory(ConfigurableBeanFactory containingFactory) {
// Set parent so that references (up container hierarchies) are correctly resolved.
DefaultListableBeanFactory internalBeanFactory = new DefaultListableBeanFactory(containingFactory);
// Required so that all BeanPostProcessors, Scopes, etc become available.
internalBeanFactory.copyConfigurationFrom(containingFactory);
// Filter out BeanPostProcessors that are part of the AOP infrastructure,
// since those are only meant to apply to beans defined in the original factory.
// 过滤掉支持AOP功能的BeanPostProcessor
internalBeanFactory.getBeanPostProcessors().removeIf(beanPostProcessor ->
beanPostProcessor instanceof AopInfrastructureBean);
return internalBeanFactory;
}
我们知道,生成代理的两个条件:
- 入口类
- 切面
新的BeanFactory(DefaultListableBeanFactory )中没有生成代理的入口类,所以没有生成代理,直接返回了目标类。
要实现上面的功能需要自定义自定义TargetSource类,继承AbstractBeanFactoryBasedTargetSource,Spring为什么要这样设计呢?
因为此时被代理实例还没进行实例化,设计成多例,多例类似于懒加载,只有用这个实例的时候才会加载:target = targetSource.getTarget();
所属类:org.springframework.aop.framework.JdkDynamicAopProxy
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object oldProxy = null;
boolean setProxyContext = false;
// 从代理工厂中获取targetSource对象,该对象包装了被代理实例
TargetSource targetSource = this.advised.targetSource;
Object target = null;
try {
// 被代理对象的equals方法和hashCode方法是不能被代理的,不会走切面
if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
// The target does not implement the equals(Object) method itself.
return equals(args[0]);
}
else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
// The target does not implement the hashCode() method itself.
return hashCode();
}
else if (method.getDeclaringClass() == DecoratingProxy.class) {
// There is only getDecoratedClass() declared -> dispatch to proxy config.
return AopProxyUtils.ultimateTargetClass(this.advised);
}
else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
method.getDeclaringClass().isAssignableFrom(Advised.class)) {
// Service invocations on ProxyConfig with the proxy config...
return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
}
Object retVal;
// 如果该属性设置为true
if (this.advised.exposeProxy) {
// Make invocation available if necessary.
// 则把代理对象设置到ThreadLocal中
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
// Get as late as possible to minimize the time we "own" the target,
// in case it comes from a pool.
// 获取被代理实例
target = targetSource.getTarget();
如果是单例的话,就会接着进行后面的实例化;反之,如果是多例,启动的时候就不会进行后面的实例化了,直接将上面这个过程中取到的Bean返回,加快了启动速度。
这种情况在日常业务中使用不多,如果一个类是多例,并且需要生成代理,可以采用这种方式,但是个人感觉比较鸡肋,但是原理需要理解。