Spring源码阅读(六)—AOP获取增强
本文主要分析了AOP功能实现中的自定义标签解析和增强的获取
个人主页:tuzhenyu’s page 原文地址:Spring源码阅读(六)—AOP获取增强
(0) Spring AOP实现的主要步骤
解析AOP自定义标签,注册AnnotationAwareAspectJAutoProxyCreator自动代理创建器
获取增强
创建代理
(1) 解析AOP自定义标签
AOP功能实现的最基本入口在XML配置文件中的AOP功能的开启;
<aop:aspectj-autoproxy>
在容器初始化解析XML配置文件会将标签分为普通标签和自定义标签分别进行解析处理.
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate
delegate) {
if (
delegate.isDefaultNamespace(root)) {
NodeList nl = root.getChildNodes();
for (
int i =
0; i < nl.getLength(); i++) {
Node node = nl.item(i);
if (node instanceof Element) {
Element ele = (Element) node;
if (
delegate.isDefaultNamespace(ele)) {
parseDefaultElement(ele,
delegate);
}
else {
delegate.parseCustomElement(ele);
}
}
}
}
else {
delegate.parseCustomElement(root);
}
}
aop标签属于自定义标签会调用相应的处理器进行处理
public BeanDefinition
parseCustomElement(Element ele, BeanDefinition containingBd) {
String namespaceUri = getNamespaceURI(ele);
NamespaceHandler handler =
this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);
if (handler ==
null) {
error(
"Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri +
"]", ele);
return null;
}
return handler.parse(ele,
new ParserContext(
this.readerContext,
this, containingBd));
}
从NamespaceHandler中获取aop的aspectj-autoproxy对应的解析器是AspectJAutoProxyBeanDefinitionParser
public void init() {
this.registerBeanDefinitionParser(
"config",
new ConfigBeanDefinitionParser());
this.registerBeanDefinitionParser(
"aspectj-autoproxy",
new AspectJAutoProxyBeanDefinitionParser());
this.registerBeanDefinitionDecorator(
"scoped-proxy",
new ScopedProxyBeanDefinitionDecorator());
this.registerBeanDefinitionParser(
"spring-configured",
new SpringConfiguredBeanDefinitionParser());
}
所有解析器都是由 BeanDefinitionParser 接口的统一实现,入口都是从 parse函数开始的
public BeanDefinition
parse(Element element, ParserContext parserContext) {
AopNamespaceUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(parserContext, element);
extendBeanDefinition(element, parserContext);
return null;
}
registerAspectJAnnotationAutoProxyCreatorIfNecessary 函数是 AnnotationAwareAspectJAutoProxyCreator 注册的地方,也是注册的主要逻辑实现的地方。主要实现了一下三个功能:
AnnotationAwareAspectJAutoProxyCreator的注册或升级
对于 proxy-target-class 以及 expose-proxy 属性的处理,用于判断是否强制使用CGLIB代理模式
注册组件并通知,便于监听器作进一步处理.
public static void registerAspectJAnnotationAutoProxyCreatorIfNecessary(ParserContext parserContext, Element sourceElement) {
BeanDefinition beanDefinition = AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(parserContext.getRegistry(), parserContext.extractSource(sourceElement));
useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);
registerComponentIfNecessary(beanDefinition, parserContext);
}
至此,aop自定义标签完成了解析,同时也将AnnotationAwareAspectJAutoProxyCreator注册到了处理器中.
(2) AOP代理实现的入口
spring 容器启动,在每个bean实例话过程中会首先尝试到缓存中获取,获取上失败后会调用createBean()方法从头创建bean.在调用doCreateBean()方法正式创建之前会调用resolveBeforeInstantiation()方法尝试是否创建代理类替代真正的实例,如果创建成功则直接返回跳过后续的真正创建过程,如果创建失败则继续创建bean实例.
Object beanInstance;
try {
beanInstance =
this.resolveBeforeInstantiation(beanName, mbd);
if(beanInstance !=
null) {
return beanInstance;
}
}
catch (Throwable var6) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", var6);
}
在resolveBeforeInstantiation()方法中会调用提前注册的处理器AnnotationAwareAspectJAutoProxyCreator的postProcessAfterInitialization()方法实现代理的创建
protected
Object resolveBeforeInstantiation(
String beanName, RootBeanDefinition mbd) {
Object bean =
null;
if(!
Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
if(!mbd.isSynthetic() &&
this.hasInstantiationAwareBeanPostProcessors()) {
Class targetType =
this.determineTargetType(beanName, mbd,
new Class[
0]);
if(targetType !=
null) {
bean =
this.applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if(bean !=
null) {
bean =
this.applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved =
Boolean.valueOf(bean !=
null);
}
return bean;
}
postProcessAfterInitialization()方法调用wrapIfNecessary()方法进行代理的实现
public Object <strong>postProcessAfterInitialization</strong>(Object bean, String beanName)
throws BeansException {
if (bean !=
null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (!
this.earlyProxyReferences.containsKey(cacheKey)) {
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
wrapIfNecessary()方法实现了aop实现的主要逻辑,调用getAdvicesAndAdvisorsForBean()提取当前bean 的所有增强方法,然后调用createProxy()方法创建具体代理.
protected Object
wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (beanName !=
null &&
this.targetSourcedBeans.containsKey(beanName)) {
return bean;
}
if (Boolean.FALSE.equals(
this.advisedBeans.
get(cacheKey))) {
return bean;
}
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
Object[] specificInterceptors = <strong>getAdvicesAndAdvisorsForBean</strong>(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;
}
(3) AOP增强的获取
getAdvicesAndAdvisorsForBean()主要是通过调用findEligibleAdvisors()方法用来获取该bean的增强列表.主要步骤包括:
寻找所有增强
从所有增强中获取适合该bean的增强.
protected List<Advisor> findEligibleAdvisors(
Class beanClass, String beanName) {
List<Advisor> candidateAdvisors = findCandidateAdvisors();
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
findCandidateAdvisors()方法是用来获取所有的增强,主要步骤包括:
获取所有在beanFactory中注册的beanName
遍历所有的beanName,判断是否为声明为AspectJ的类,如果是则进行进一步处理
对标记为AspectJ注解的类进行增强器的提取
将提取结果放入缓存
protected List<Advisor>
findCandidateAdvisors() {
List advisors =
super.findCandidateAdvisors();
advisors.addAll(
this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
return advisors;
}
public List<Advisor>
buildAspectJAdvisors() {
List aspectNames =
null;
synchronized(
this) {
aspectNames =
this.aspectBeanNames;
if(aspectNames ==
null) {
LinkedList var16 =
new LinkedList();
LinkedList var15 =
new LinkedList();
String[] var17 = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Object.class,
true,
false);
String[] var18 = var17;
int var19 = var17.length;
for(
int var7 =
0; var7 < var19; ++var7) {
String beanName = var18[var7];
if(
this.isEligibleBean(beanName)) {
Class beanType =
this.beanFactory.getType(beanName);
if(beanType !=
null &&
this.advisorFactory.isAspect(beanType)) {
var15.add(beanName);
AspectMetadata amd =
new AspectMetadata(beanType, beanName);
if(amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
BeanFactoryAspectInstanceFactory factory1 =
new BeanFactoryAspectInstanceFactory(
this.beanFactory, beanName);
List classAdvisors =
this.advisorFactory.getAdvisors(factory1);
if(
this.beanFactory.isSingleton(beanName)) {
this.advisorsCache.put(beanName, classAdvisors);
}
else {
this.aspectFactoryCache.put(beanName, factory1);
}
var16.addAll(classAdvisors);
}
else {
if(
this.beanFactory.isSingleton(beanName)) {
throw new IllegalArgumentException(
"Bean with name \'" + beanName +
"\' is a singleton, but aspect instantiation model is not singleton");
}
PrototypeAspectInstanceFactory var20 =
new PrototypeAspectInstanceFactory(
this.beanFactory, beanName);
this.aspectFactoryCache.put(beanName, var20);
var16.addAll(
this.advisorFactory.getAdvisors(var20));
}
}
}
}
this.aspectBeanNames = var15;
return var16;
}
}
调用findAdvisorsThatCanApply()方法从所有增强中获取适合该bean的增强
protected List<Advisor> findAdvisorsThatCanApply(
List<Advisor> candidateAdvisors,
Class<?> beanClass, String beanName) {
ProxyCreationContext.setCurrentProxiedBeanName(beanName);
List var4;
try {
var4 = AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
}
finally {
ProxyCreationContext.setCurrentProxiedBeanName((String)
null);
}
return var4;
}
(4) 总结
AOP功能的实现是从XML配置文件中的aop标签解析开始的,标签的解析会注册代理自动创建器用于后续的调用.当从容器中尝试获取bean的时候会在真正创建bean之前尝试创建代理,创建代理主要包括增强的获取和代理的创建两部分,这篇博文主要分析了增强获取的主要流程.