代理对象在项目启动时生成 ,代理对象生成之后,就会被加入到单例缓冲池中。
而我们的目标对象只是作为代理对象的一个属性存在而已。也就是说,你无法在Spring 容器中直接找到目标对象,但是你可以在Spring 容器中直接找到代理对象。
实例化Bean的过程是在AbstractAutowireCapableBeanFactory的``doCreateBean方法中完成的。在属性依赖注入后(也就是执行完populateBean后 )。调用了initializeBean`方法。这个方法为Bean添加了后置处理器。
applyBeanPostProcessorsAfterInitialization方法来应用后置处理器。而在这个方法中,遍历了所有的BeanPostProcessor,并且调用了BeanPostProcessor的后置处理方法postProcessAfterInitialization。
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
// 调用JDK的安全验证机制
if (System.getSecurityManager() != null) {
// 实现PrivilegedAction接口的匿名内部类
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
} else {
// 为bean实例包装相关属性:如名称、类加载器、所属容器等。
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
// 如果Bean定义不为null或者bean定义不是合成的.
if (mbd == null || !mbd.isSynthetic()) {
// 调用BeanPostProcessors后置处理器,在Bean初始化之前做一些处理
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
// 调用bean实例初始化方法。这个方法是在SpringBean定义配置文件中通过init-method属性指定的
// xml配置和注解配置、JSR注解配置是一样的。
invokeInitMethods(beanName, wrappedBean, mbd);
} catch (Throwable ex) {...省略异常信息...}
if (mbd == null || !mbd.isSynthetic()) {
// 调用BeanPostProcessors后置处理器,在Bean初始化之后做一些处理
// 此方法中aop的入口
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
// bean实例 初始化之后执行
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
// 调用所有后置处理器额方法。
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
可以看出在其中调用了applyBeanPostProcessorsAfterInitialization方法来应用后置处理器。而在这个方法中,遍历了所有的BeanPostProcessor,并且调用了BeanPostProcessor的后置处理方法postProcessAfterInitialization。
上面刚说过,BeanPostProcessor的实现类由很多。完成AOP的类是AbstractAutoProxyCreator,所以只看这个类的postProcessAfterInitialization方法:
initializeBean:
// 如果子类将bean标识为要代理的bean,则使用已配置的侦听器创建代理
@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
// core1 必要时包裹
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
在这里面调用了一个核心方法wrapIfNecessary,
```java
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
// 如果beanName有长度。并且代理源beans包含这个beanName。就直接返回
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
// 判断是否需要代理这个Bean
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
// 如果是基础类,或者应该跳过的类,
// 所谓isInfrastructureClass就是指,Advice,PointCut,Advisor
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
// Create proxy if we have advice.
// 如果有通知,就创建代理。
// 获取这个Bean的通知
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
// 创建代理
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
//可以看到有一个createProxy创建代理对象。
protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
@Nullable Object[] specificInterceptors, TargetSource targetSource) {
...省略不重要信息...
// core1. 重代理工厂中获取代理对象。通过classLoader
return proxyFactory.getProxy(getProxyClassLoader());
}
public Object getProxy(@Nullable ClassLoader classLoader) {
// core1.
return createAopProxy().getProxy(classLoader);
}
其中createAopProxy()方法,就是创建了了一个工厂,后面是调用工厂的getProxy来生产代理对象。
createAopProxy其实就是选择代理策略——使用JDK动态代理或是CGLIB动态代理。
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
Class<?> targetClass = config.getTargetClass();
if (targetClass == null) {
throw new AopConfigException("TargetSource cannot determine target class: " +
"Either an interface or a target is required for proxy creation.");
}
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
// core1 JdkDynamicAopProxy
return new JdkDynamicAopProxy(config);
}
// core2 ObjenesisCglibAopProxy
return new ObjenesisCglibAopProxy(config);
}
else {
// core1 JdkDynamicAopProxy
return new JdkDynamicAopProxy(config);
}
}
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isTraceEnabled()) {
logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
}
// 获取所有的代理接口
Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}
JDK动态代理很经典的调用了Proxy.newProxyInstance来创建代理对象。至于CGLIB同样也是返回的代理对象
返回代理的对象
至此,可以看出,如果Bean想要使用AOP增强,那么initializeBean方法实际上返回的是一个被代理过得Bean对象。initializeBean方法继续往高层返回对象到IoC容器中(也就是初始化Bean)。最后容器中放入的Bean就是实现了AOP理念的Bean对象。
返回对象
↓↓↓↓
initializeBean——————>doCreateBean——>createBean——>doGetBean——>getBean——>preInstantiateSingletons——>finishBeanFactoryInitialization——>refresh——>构造方法。