概述
簡單來說,代理對象的創建是在bean的創建生命週期中的postProcessAfterInitialization方法調用時完成的,而幹這件事的BeanPostProcessor 就是 AnnotationAwareAspectJAutoProxyCreator
關於bean的創建生命週期不再過多講解,感興趣可以看看我之前的文章
AnnotationAwareAspectJAutoProxyCreator的註冊和創建
我們普通的bean的後置處理需要先有這些後置處理器,那麼我們先看看這個後置處理器的註冊和創建過程。這裏我們需要搞清楚,註冊和創建是不同的,註冊的過程可以簡單理解爲把這個類的信息封裝成BeanDefinition放入緩存,創建過程是用BeanDefinition作爲原料,經過一些列的處理生成一個對象。
註冊
註冊有兩種方式,一種是通過xml 引入命名空間 聲明
<aop:aspectj-autoproxy />
或者通過Javaconfig
@Configuration
@ComponentScan
@EnableAspectJAutoProxy
public class Config {
public static void main(String[] args) {
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(Config.class);
DoHi doHi = (DoHi)ac.getBean("doHi");
doHi.kill();
}
}
對於前一種方式暫時不作詳細解釋,我們現在來研究下通過JavaConfig的方式完成的註冊
這時候需要先看看EnableAspectJAutoProxy這個註解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
// true則強制使用AspectJ來實現代理
boolean proxyTargetClass() default false;
// true則可以暴露代理對象,可以用來解決同一個類中調用代理失效的問題
boolean exposeProxy() default false;
}
我們應該注意到這個註解有個@Import,我們接着看些這個導入的配置類
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
/**
* Register, escalate, and configure the AspectJ auto proxy creator based on the value
* of the @{@link EnableAspectJAutoProxy#proxyTargetClass()} attribute on the importing
* {@code @Configuration} class.
*/
@Override
public void registerBeanDefinitions(
AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
//這裏完成了AnnotationAwareAspectJAutoProxyCreator的註冊
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
//這裏完成了上述兩個屬性的設置
AnnotationAttributes enableAspectJAutoProxy =
AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}
}
總體來說,它通過Import導入一個實現了ImportBeanDefinitionRegistrar 接口的對象來完成了註冊
創建
創建過程需要進入著名的Refresh方法
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// 我們的處理器正是在這個地方註冊
registerBeanPostProcessors(beanFactory);
...
}
...
}
}
進入方法registerBeanPostProcessors
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
// Register BeanPostProcessorChecker that logs an info message when
// a bean is created during BeanPostProcessor instantiation, i.e. when
// a bean is not eligible for getting processed by all BeanPostProcessors.
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
// Separate between BeanPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
List<BeanPostProcessor> internalPostProcessors = new ArrayList<BeanPostProcessor>();
List<String> orderedPostProcessorNames = new ArrayList<String>();
List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
priorityOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
// First, register the BeanPostProcessors that implement PriorityOrdered.
sortPostProcessors(beanFactory, priorityOrderedPostProcessors);
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
// Next, register the BeanPostProcessors that implement Ordered.
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<BeanPostProcessor>();
for (String ppName : orderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
sortPostProcessors(beanFactory, orderedPostProcessors);
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
// Now, register all regular BeanPostProcessors.
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
for (String ppName : nonOrderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
// Finally, re-register all internal BeanPostProcessors.
sortPostProcessors(beanFactory, internalPostProcessors);
registerBeanPostProcessors(beanFactory, internalPostProcessors);
// Re-register post-processor for detecting inner beans as ApplicationListeners,
// moving it to the end of the processor chain (for picking up proxies etc).
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
上面的邏輯可以簡單理解爲,通過Class找到合適的beanName,然後根據是否實現了優先級或排序的接口被放入三組,然後排序,這過程中完成了對bean的創建,其過程與普通bean的創建一樣,也是調用getBean方法。然後這些處理器就作爲beanfactory的屬性被存儲下來,方便對普通bean的創建的處理。
通知的創建
如上面所言,我們的後置處理器已經創建完成,那我們開始普通bean的創建,跳過創建生命週期的其它步驟,直接進入後置處理器的方法調用
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
...
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
//代理創建正是在這裏進行的
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
代理對象的創建
致謝
感謝 簡書 作者王偵的文章 爲我搞清楚spring aop的原理提供的思路
博客 地址
我大致順着他的思路重寫一遍