《Spring源码深度解析》
spring-framework-reference
AOP使用示例
maven依赖
添加aop和aspcetj依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.framework.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.7.4</version>
</dependency>
实现代码
Service
public class BookServiceImpl implements BookService {
@Override
public void printBook(Book entity) {
System.out.println(entity);
}
}
Aspcet
@Aspect
public class LogAspect {
//execution(<修饰符模式>?<返回类型模式><方法名模式>(<参数模式>)<异常模式>?)
//第一个* 为返回值
//第二个* 表示包结构
//随后跟随的 .. 表示 package以及子包
//第三个* 表示类名
//第四个 print* 表示 以print开头的方法名
//(..) 表示任意个数 参数
@Pointcut(value = "execution(public * *..*.print*(..))" )
public void logPointCut(){
}
@Before(value = "logPointCut()")
public void before(){
System.out.println("-------------------before");
}
@After(value = "logPointCut()")
public void after(){
System.out.println("-------------------after");
}
@Around(value = "logPointCut()")
public Object around(ProceedingJoinPoint joinPoint){
System.out.println("***around begin***");
Object o = null;
try {
o = joinPoint.proceed();
} catch (Throwable throwable) {
}
System.out.println("***around end***");
return o;
}
}
applicationContext.xml
<!-- 开启aop 注解 -->
<aop:aspectj-autoproxy/>
<bean class="spring.chap07.aop.LogAspect"/>
<bean id="bookService" class="spring.chap07.service.impl.BookServiceImpl"/>
Test
@Test
public void test05() {
AbstractApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
BookService bookService = context.getBean("bookService", BookService.class);
bookService.printBook(new Book("111","Trump传",12.34d));
}
打印结果:
AOP自定义标签
在AOP-${version}.jar/META-INF/spring.handlers
文件中,定义了自定义标签处理器,它的内容如下:
http\://www.springframework.org/schema/aop=org.springframework.aop.config.AopNamespaceHandler
aop的自定义标签,由AopNamespaceHandler
来处理,它的代码如下:
//org.springframework.aop.config.AopNamespaceHandler
public class AopNamespaceHandler extends NamespaceHandlerSupport {
public void init() {
//1. <aop:config> xml模式配置aop
registerBeanDefinitionParser("config", new ConfigBeanDefinitionParser());
//2. <aop:aspectj-autoproxy> 开启aop注解模式
registerBeanDefinitionParser("aspectj-autoproxy", new AspectJAutoProxyBeanDefinitionParser());
//<aop:scoped-proxy>
registerBeanDefinitionDecorator("scoped-proxy", new ScopedProxyBeanDefinitionDecorator());
// 2.1之后移至 <context:spring-configured>
registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser());
}
}
1. <aop:config>
spring开启aop 可以通过<aop:config>
xml配置模式,也可以通过后面的<aop:aspectj-autoproxy>
开启注解模式。
1.1 xml配置模式
- <aop:aspect>
<bean id="logAspectXml" class="spring.chap07.aop.LogAspectXml"/>
<aop:config>
<aop:pointcut id="logPointCut" expression="execution(public * *..*.print*(..))"/>
<aop:aspect ref="logAspectXml">
<!– around 与 before,after 有先后顺序. –>
<aop:before method="before" pointcut-ref="logPointCut"/>
<aop:after method="after" pointcut-ref="logPointCut"/>
<aop:around method="around" pointcut-ref="logPointCut"/>
</aop:aspect>
</aop:config>
- <aop:advisor>
<!-- LogAdviceXml需要实现Advice接口,
一般使用MethodBeforeAdvice,MethodInterceptor接口,
或者继承(extends) AfterAdvice类
-->
<bean id="logAdviceXml" class="spring.chap07.aop.LogAdviceXml"/>
<aop:config>
<aop:pointcut id="logPointCut" expression="execution(public * *..*.print*(..))"/>
<aop:advisor advice-ref="logAdviceXml" order="1" pointcut-ref="logPointCut"/>
</aop:config>
1.2 ConfigBeanDefinitionParser-解析过程
<aop:config>
通过ConfigBeanDefinitionParser
来解析,它解析三类标签:
-
pointCut
: 最终注册的beanclassAspectJExpressionPointcut
-
advisor
: 注册为DefaultBeanFactoryPointcutAdvisor
-
aspect
: 注册为AspectJPointcutAdvisor
,public AspectJPointcutAdvisor(AbstractAspectJAdvice advice) { this.advice = advice; this.pointcut = advice.buildSafePointcut(); }
其中构造参数
Advice
的类型由Aop方法来确定:before
:AspectJMethodBeforeAdvice
after
:AspectJAfterAdvice
after-returning
:AspectJAfterReturningAdvice
after-throwing
:AspectJAfterThrowingAdvice
around
:AspectJAroundAdvice
2. <aop:aspectj-autoproxy>
<aop:aspectj-autoproxy>
是由AspectJAutoProxyBeanDefinitionParser
来解析处理的。
对于所有的解析器,都是实现了BeanDefinitionParser
接口,他们的入口方法为parse()
.
//org.springframework.aop.config.AspectJAutoProxyBeanDefinitionParser
class AspectJAutoProxyBeanDefinitionParser implements BeanDefinitionParser {
//方法入口:parse
public BeanDefinition parse(Element element, ParserContext parserContext) {
//1.注册 AspectJAnnotationAutoProxyCreator
AopNamespaceUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(parserContext, element);
//2.对于注解中子类的处理
extendBeanDefinition(element, parserContext);
return null;
}
}
1.registerAspectJAnnotationAutoProxyCreatorIfNecessary
//org.springframework.aop.config.AopNamespaceUtils
public abstract class AopNamespaceUtils {
public static final String PROXY_TARGET_CLASS_ATTRIBUTE = "proxy-target-class";
private static final String EXPOSE_PROXY_ATTRIBUTE = "expose-proxy";
public static void registerAspectJAnnotationAutoProxyCreatorIfNecessary(
ParserContext parserContext, Element sourceElement) {
//1.1 注册 AnnotationAwareAspectJAutoProxyCreator
BeanDefinition beanDefinition = AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(
parserContext.getRegistry(), parserContext.extractSource(sourceElement));
//1.2 填充 "proxy-target-class","expose-proxy" 属性
useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);
//1.3 向监听器注册组件
registerComponentIfNecessary(beanDefinition, parserContext);
}
}
- 1.1 注册 AnnotationAwareAspectJAutoProxyCreator
//org.springframework.aop.config.AopConfigUtils
public abstract class AopConfigUtils {
public static final String AUTO_PROXY_CREATOR_BEAN_NAME = "org.springframework.aop.config.internalAutoProxyCreator";
private static final List<Class> APC_PRIORITY_LIST = new ArrayList<Class>();
static {
APC_PRIORITY_LIST.add(InfrastructureAdvisorAutoProxyCreator.class);
APC_PRIORITY_LIST.add(AspectJAwareAdvisorAutoProxyCreator.class);
APC_PRIORITY_LIST.add(AnnotationAwareAspectJAutoProxyCreator.class);
}
//注册 AnnotationAwareAspectJAutoProxyCreator
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, Object source) {
return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}
private static BeanDefinition registerOrEscalateApcAsRequired(Class cls, BeanDefinitionRegistry registry, Object source) {
if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
//如果容器内已经注册了AUTO_PROXY_CREATOR_BEAN_NAME,则取出现存的BeanDefinition,最终返回null(即表示无需注册)
BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
//获取BeanClass在APC_PRIORITY_LIST列表中的index作为优先级, index越大则优先级越高
int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
int requiredPriority = findPriorityForClass(cls);
//当前优先级 < cls的优先级,则更新BeanDefinition的className
if (currentPriority < requiredPriority) {
apcDefinition.setBeanClassName(cls.getName());
}
}
return null;
}
//如果容器中不包含AUTO_PROXY_CREATOR_BEAN_NAME,则需要注册
//构造RootBeanDefinition()
RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
beanDefinition.setSource(source);
beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
//注册至registry
registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
return beanDefinition;
}
//获取clazz在APC_PRIORITY_LIST中的index作为优先级.
private static int findPriorityForClass(Class clazz) {
return APC_PRIORITY_LIST.indexOf(clazz);
}
}
- 1.2 填充 “proxy-target-class”,“expose-proxy” 属性
//org.springframework.aop.config.AopNamespaceUtils
//1.2 若xml配置了"proxy-target-class"或"expose-proxy"属性为true,
// 如 <aop:aspectj-autoproxy expose-proxy="true" proxy-target-class="true" />
//则为beanDefinition添加同名属性
private static void useClassProxyingIfNecessary(BeanDefinitionRegistry registry, Element sourceElement) {
if (sourceElement != null) {
boolean proxyTargetClass = Boolean.valueOf(sourceElement.getAttribute(PROXY_TARGET_CLASS_ATTRIBUTE));
if (proxyTargetClass) {
//最终调用逻辑:definition.getPropertyValues().add("proxyTargetClass", Boolean.TRUE);
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
boolean exposeProxy = Boolean.valueOf(sourceElement.getAttribute(EXPOSE_PROXY_ATTRIBUTE));
if (exposeProxy) {
//definition.getPropertyValues().add("exposeProxy", Boolean.TRUE);
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}
}
-
proxy-target-class: SpringAOP使用
JDK动态代理
或CGLIB
来为目标对象创建代理。proxy-target-class="true"
表示强制使用CGLIB实现动态代理。JDK动态代理
: 被代理对象必须至少实现一个接口CGLIB动态代理
:从字节码层面实现,为代理对象创建子类作为代理对象。(无法为final类,final方法创建代理类、代理方法);
更多,可查阅 java代理模式
-
expose-proxy:暴露代理对象。(解决AOP增强丢失的问题,使用
AopContext.currentProxy().xxMethod()
)
多知道一点 — AOP增强丢失
构造示例
Service
public class LostServiceImpl implements LostService {
@Override
public void a() {
System.out.println("a");
this.b();
}
@Override
public void b() {
System.out.println("b");
}
}
Aspect
@Aspect
public class LostLogAspect {
@Pointcut(value = "execution(public * *..LostService.*(..))" )
public void logPointCut(){
}
@Before(value = "logPointCut()")
@Order(value=1)
public void before(){
System.out.println("LostLogAspect-------------------before");
}
}
Test case
@Test
public void test02() {
AbstractApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
LostService lostService = context.getBean("lostService", LostService.class);
lostService.a();
}
打印结果:
原因是在方法a()中,this.b()
,此时的this指定的是目标对象target
,并不是代理对象,导致失效对象失败。
方法一:
//1.xml 中开启expose-proxy
<aop:aspectj-autoproxy expose-proxy="true" />
//2.java中将this.b() 改为:
((LostService) AopContext.currentProxy()).b();
方法二 ---- 优雅解决
参考Spring中各种常见的Aware的做法,将proxy对象注册到自身
定义接口:BeanSelfAware
public interface BeanSelfAware {
void setSelf(Object proxy);
}
Service实现BeanSelfAware接口,将代理对象赋值给自己
public class LostServiceImpl implements LostService , BeanSelfAware {
private LostService proxy;
@Override
public void setSelf(Object proxy) {
this.proxy = (LostService) proxy;
}
@Override
public void a() {
proxy.b();
}
}
自定义BeanPostProcessor
public class BeanSelfAwareBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof BeanSelfAware){
BeanSelfAware beanSelfAware = (BeanSelfAware)bean;
beanSelfAware.setSelf(bean);
return beanSelfAware;
}
return bean;
}
}
2.extendBeanDefinition
加载<aop:aspectj-autoproxy>
子元素。
<aop:aspectj-autoproxy expose-proxy="true" proxy-target-class="true" >
<aop:include name="logAspect"/>
<aop:include name="thatBean"/>
</aop:aspectj-autoproxy>
它的作用表示: 只有满足@Aspect bean至少满足一个 <aop:include>name属性配置,才有效
//org.springframework.aop.config.AspectJAutoProxyBeanDefinitionParser
private void extendBeanDefinition(Element element, ParserContext parserContext) {
BeanDefinition beanDef = parserContext.getRegistry().getBeanDefinition(AopConfigUtils.AUTO_PROXY_CREATOR_BEAN_NAME);
if (element.hasChildNodes()) {
addIncludePatterns(element, parserContext, beanDef);
}
}
private void addIncludePatterns(Element element, ParserContext parserContext, BeanDefinition beanDef) {
ManagedList<TypedStringValue> includePatterns = new ManagedList<TypedStringValue>();
NodeList childNodes = element.getChildNodes();
//for-each 获取子元素
for (int i = 0; i < childNodes.getLength(); i++) {
Node node = childNodes.item(i);
if (node instanceof Element) {
Element includeElement = (Element) node;
//获取子元素的 name属性
TypedStringValue valueHolder = new TypedStringValue(includeElement.getAttribute("name"));
valueHolder.setSource(parserContext.extractSource(includeElement));
includePatterns.add(valueHolder);
}
}
if (!includePatterns.isEmpty()) {
includePatterns.setSource(parserContext.extractSource(element));
//将name 属性集合,设置到"includePatterns"属性
beanDef.getPropertyValues().add("includePatterns", includePatterns);
}
}
3. <aop:scoped-proxy> (…)
获取增强器
上文讲到了通过<aop:aspectj-autoproxy>
注册了AnnotationAwareAspectJAutoProxyCreator
,这个类是如何完成AOP的操作的呢?
首先观察它的类图:
AnnotationAwareAspectJAutoProxyCreator
实现了BeanPostProcessor
接口,它的直接实现类在AbstractAutoProxyCreator
中实现。
//org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator ---320
public abstract class AbstractAutoProxyCreator extends ProxyConfig
implements SmartInstantiationAwareBeanPostProcessor, BeanClassLoaderAware, BeanFactoryAware,
Ordered, AopInfrastructureBean {
//标记 cacheKey 是否需要标记, 当代理完成之后,标记为false.
private final Map<Object, Boolean> advisedBeans = new ConcurrentHashMap<Object, Boolean>(64);
private final Map<String, Boolean> targetSourcedBeans = new ConcurrentHashMap<String, Boolean>(16);
private final Map<Object, Boolean> earlyProxyReferences = new ConcurrentHashMap<Object, Boolean>(16);
//存放 cacheKey --> proxyClass
private final Map<Object, Class<?>> proxyTypes = new ConcurrentHashMap<Object, Class<?>>(16);
protected static final Object[] DO_NOT_PROXY = null;
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean != null) {
//getCacheKey逻辑为 return beanClass.getName() + "_" + beanName ;
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (!this.earlyProxyReferences.containsKey(cacheKey)) {
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
//如果已经处理过
if (beanName != null && this.targetSourcedBeans.containsKey(beanName)) {
return bean;
}
//cacheKey 无需增强
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
//如果是基础设施类(Advice,Advisor,AopInfrastructureBean)则无需代理
//shouldSkip 默认返回false, 可由子类覆盖实现
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
//标记该bean无需增强, 并放入advisedBeans
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
// 1.寻找匹配到的 增强方法 -- abstract方法,由子类实现
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
// 如果匹配到增强方法,需要针对增强创建代理
if (specificInterceptors != DO_NOT_PROXY) {
//标记该bean需增强, 并放入advisedBeans
this.advisedBeans.put(cacheKey, Boolean.TRUE);
//2.创建代理
Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
//创建代理完成之后,标记为false
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
}
调用getAdvicesAndAdvisorsForBean
方法的逻辑主要包括两个部分:
- 获取增强器
- 根据pointcut 匹配增强器
//org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator
public abstract class AbstractAdvisorAutoProxyCreator extends AbstractAutoProxyCreator {
@Override
protected Object[] getAdvicesAndAdvisorsForBean(Class beanClass, String beanName, TargetSource targetSource) {
List advisors = findEligibleAdvisors(beanClass, beanName);
if (advisors.isEmpty()) {
return DO_NOT_PROXY;
}
return advisors.toArray();
}
protected List<Advisor> findEligibleAdvisors(Class beanClass, String beanName) {
//1.获取候选Advisors -- 由子类 AnnotationAwareAspectJAutoProxyCreator 完成
List<Advisor> candidateAdvisors = findCandidateAdvisors();
//2.获取匹配的Advisors
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
}
1. 获取增强器 — findCandidateAdvisors
获取增强器方法,由AnnotationAwareAspectJAutoProxyCreator
实现findCandidateAdvisors
获取候选Advisors
//org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator
private BeanFactoryAspectJAdvisorsBuilder aspectJAdvisorsBuilder;
@Override
protected List<Advisor> findCandidateAdvisors() {
// 调用父类方法,获取所有xml配置的 advisor
List<Advisor> advisors = super.findCandidateAdvisors();
// 获取所有@Aspect注解的advisor
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
return advisors;
}
1. super.findCandidateAdvisors()
//org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator
private BeanFactoryAdvisorRetrievalHelper advisorRetrievalHelper;
protected List<Advisor> findCandidateAdvisors() {
//调用BeanFactoryAdvisorRetrievalHelper来获取 advisorbeans
return this.advisorRetrievalHelper.findAdvisorBeans();
}
//
//org.springframework.aop.framework.autoproxy.BeanFactoryAdvisorRetrievalHelper
public class BeanFactoryAdvisorRetrievalHelper {
private String[] cachedAdvisorBeanNames;
public List<Advisor> findAdvisorBeans() {
String[] advisorNames = null;
synchronized (this) {
//首先从缓存中获取
advisorNames = this.cachedAdvisorBeanNames;
//如果缓存中获取为空,则需要重新从spring容器中获取
if (advisorNames == null) {
//获取容器汇总所有 Advisor类型的bean
advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Advisor.class, true, false);
this.cachedAdvisorBeanNames = advisorNames;
}
}
if (advisorNames.length == 0) {
return new LinkedList<Advisor>();
}
List<Advisor> advisors = new LinkedList<Advisor>();
for (String name : advisorNames) {
if (isEligibleBean(name)) {
if (this.beanFactory.isCurrentlyInCreation(name)) {
//如果 bean 没有创建完成,则跳过
} else {
advisors.add(this.beanFactory.getBean(name, Advisor.class));
}
}
}
return advisors;
}
}
2. aspectJAdvisorsBuilder.buildAspectJAdvisors()
//springframework.aop.aspectj.annotation.BeanFactoryAspectJAdvisorsBuilder
private List<String> aspectBeanNames;
public List<Advisor> buildAspectJAdvisors() {
List<String> aspectNames = null;
synchronized (this) {
aspectNames = this.aspectBeanNames;
if (aspectNames == null) {
//如果缓存 aspectBeanNames 为 null
List<Advisor> advisors = new LinkedList<Advisor>();
aspectNames = new LinkedList<String>();
//获取容器中所有的bean
String[] beanNames =
BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.beanFactory, Object.class, true, false);
for (String beanName : beanNames) {
if (!isEligibleBean(beanName)) {
continue;
}
//获取bean类型
Class beanType = this.beanFactory.getType(beanName);
if (beanType == null) {
continue;
}
//如果实现了@Aspect注解 且 没有field以 "ajc$" 为前缀命名
if (this.advisorFactory.isAspect(beanType)) {
aspectNames.add(beanName);
AspectMetadata amd = new AspectMetadata(beanType, beanName);
if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
MetadataAwareAspectInstanceFactory factory =
new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
//1. 解析带有aspectj 注解标记的方法(如@before, @after)
List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
if (this.beanFactory.isSingleton(beanName)) {
//如果是单例, 则缓存 classAdvisors
this.advisorsCache.put(beanName, classAdvisors);
} else {
//如果不是单例, 则缓存 factory
this.aspectFactoryCache.put(beanName, factory);
}
//添加 classAdvisors
advisors.addAll(classAdvisors);
} else {
MetadataAwareAspectInstanceFactory factory =
new PrototypeAspectInstanceFactory(this.beanFactory, beanName);
this.aspectFactoryCache.put(beanName, factory);
advisors.addAll(this.advisorFactory.getAdvisors(factory));
}
}
}
this.aspectBeanNames = aspectNames;
return advisors;
}
}
// 如果缓存aspectBeanNames != null,直接从缓存中取。
if (aspectNames.isEmpty()) {
return Collections.EMPTY_LIST;
}
List<Advisor> advisors = new LinkedList<Advisor>();
for (String aspectName : aspectNames) {
//首先尝试从 advisorsCache 缓存中获取。
List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName);
if (cachedAdvisors != null) {
advisors.addAll(cachedAdvisors);
} else {
//尝试从 aspectFactoryCache缓存中获取factory缓存,然后在通过factory获取advisor
MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName);
advisors.addAll(this.advisorFactory.getAdvisors(factory));
}
}
return advisors;
}
上述代码完成了对Advisor
的提取,在上面的步骤中最为重要复杂的就是增强器的获取。这一功能委托给了getAdvisors
方法去实现。
2.1 AspectJAdvisorFactory.getAdvisors(factory)
//org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory
public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory maaif) {
//获取标记为Aspectj的类
final Class<?> aspectClass = maaif.getAspectMetadata().getAspectClass();
final String aspectName = maaif.getAspectMetadata().getAspectName();
validate(aspectClass);
final MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =
new LazySingletonAspectInstanceFactoryDecorator(maaif);
final List<Advisor> advisors = new LinkedList<Advisor>();
//getAdvisorMethods: 获取aspectClass中所有 未带有@pointcut 标记的方法 ,并排序
for (Method method : getAdvisorMethods(aspectClass)) {
//a. 获取普通 Advisor
Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName);
if (advisor != null) {
advisors.add(advisor);
}
}
// 如果配置了 lazy-init
if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
//b. 获取 SyntheticInstantiationAdvisor
Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory);
advisors.add(0, instantiationAdvisor);
}
for (Field field : aspectClass.getDeclaredFields()) {
// 带有@DeclareParents 注解的field
Advisor advisor = getDeclareParentsAdvisor(field);
if (advisor != null) {
advisors.add(advisor);
}
}
return advisors;
}
//a.
public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aif,
int declarationOrderInAspect, String aspectName) {
validate(aif.getAspectMetadata().getAspectClass());
//获取pointcut
AspectJExpressionPointcut ajexp =
getPointcut(candidateAdviceMethod, aif.getAspectMetadata().getAspectClass());
if (ajexp == null) {
return null;
}
//构建advisor: 首先确定advice的类型,然后+pointcut 构建advisor
return new InstantiationModelAwarePointcutAdvisorImpl(
this, ajexp, aif, candidateAdviceMethod, declarationOrderInAspect, aspectName);
}
//b.
protected static class SyntheticInstantiationAdvisor extends DefaultPointcutAdvisor {
public SyntheticInstantiationAdvisor(final MetadataAwareAspectInstanceFactory aif) {
super(aif.getAspectMetadata().getPerClausePointcut(), new MethodBeforeAdvice() {
//目标方法调用前, 类似@before
public void before(Method method, Object[] args, Object target) {
aif.getAspectInstance();
}
});
}
}
//c. 注册DeclareParentsAdvisor 它实现了IntroductionAdvisor接口
private Advisor getDeclareParentsAdvisor(Field introductionField) {
//field带有@DeclareParents 注解
DeclareParents declareParents = introductionField.getAnnotation(DeclareParents.class);
if (declareParents == null) {
return null;
}
if (DeclareParents.class.equals(declareParents.defaultImpl())) {
throw new IllegalStateException("defaultImpl must be set on DeclareParents");
}
return new DeclareParentsAdvisor(
introductionField.getType(), declareParents.value(), declareParents.defaultImpl());
}
多知道一点 — @DeclareParents
@DeclareParents
指定满足指定表达式的类将自动实现某些接口。
@Aspect
@Component
public class AspectConfig {
//"+"表示A的所有子类;
// BImpl 表示默认需要添加的新的类
//表示为所有A的子类 添加B接口, 接口默认实现为:BImpl ; 如果已经实现了B类型接口,则aop拦截无效;
@DeclareParents(value = "A+", defaultImpl = BImpl.class)
public B b;
}
2. 寻找匹配的增强器 — findAdvisorsThatCanApply
//org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator
protected List<Advisor> findAdvisorsThatCanApply(
List<Advisor> candidateAdvisors, Class beanClass, String beanName) {
ProxyCreationContext.setCurrentProxiedBeanName(beanName);
try {
//过滤已经得到的 advisor
return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
} finally {
ProxyCreationContext.setCurrentProxiedBeanName(null);
}
}
过滤操作委托给AopUtils.findAdvisorsThatCanApply
来实现。
AopUtils.findAdvisorsThatCanApply()
在查看AopUtils.findAdvisorsThatCanApply
之前,我们需要先了解一下:
Advisor分两大类:IntroductionAdvisor(引介通知器)和PointcutAdvisor(切点通知器)。
两类Advisor都是为了增强targetClass,但是作用不一样。
- IntroductionAdvisor 主要为了给targetClass追加接口(或者说追加更多的方法),这种增强属于类级别的增强;
- 而PointcutAdvisor主要为了拦截方法,这种增强属于方法级别的增强。
正是由于两类Advisor的增强级别不同,而导致了对ClassFilter的使用方式不同。
- IntroductionAdvisor进行类级别增强,因此只需要直接持有ClassFilter即可;
- 而PointcutAdvisor进行方法级别增强,因此需要同时使用ClassFilter和MethodMatcher(方法匹配器)。PointcutAdvisor内部持有一个Pointcut,而Pointcut就是由ClassFilter和MethodMatcher组成的。
//org.springframework.aop.support.AopUtils
public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
if (candidateAdvisors.isEmpty()) {
return candidateAdvisors;
}
List<Advisor> eligibleAdvisors = new LinkedList<Advisor>();
for (Advisor candidate : candidateAdvisors) {
//如果是 IntroductionAdvisor && clazz满足 匹配规则
if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
eligibleAdvisors.add(candidate);
}
}
boolean hasIntroductions = !eligibleAdvisors.isEmpty();
for (Advisor candidate : candidateAdvisors) {
if (candidate instanceof IntroductionAdvisor) {
continue;
}
// 通过ponitcut 匹配..
if (canApply(candidate, clazz, hasIntroductions)) {
eligibleAdvisors.add(candidate);
}
}
return eligibleAdvisors;
}
public static boolean canApply(Advisor advisor, Class<?> targetClass) {
return canApply(advisor, targetClass, false);
}
public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
if (advisor instanceof IntroductionAdvisor) {
return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass);
} else if (advisor instanceof PointcutAdvisor) {
PointcutAdvisor pca = (PointcutAdvisor) advisor;
return canApply(pca.getPointcut(), targetClass, hasIntroductions);
} else {
return true;
}
}
多知道一点 — Spring提供多种AOP代理方法
Spring提供多种AOP代理方法,他们都继承自AbstractAutoProxyCreator
AnnotationAwareAspectJAutoProxyCreator
: 根据Bean中的AspectJ注解自动创建代理(<aop:aspectj-autoproxy>
)BeanNameAutoProxyCreator
:根据配置的beanNames创建代理(支持通配符,拦截的是类
)DefaultAdvisorAutoProxyCreator
根据Advisor的匹配机制自动创建代理,会对容器中所有的Advisor进行扫描,自动将这些切面应用到匹配的Bean中
BeanNameAutoProxyCreator
<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="beanNames">
<list>
<!-- 支持正则 -->
<value>*Service</value>
<value>lostService</value>
</list>
</property>
<property name="interceptorNames">
<list>
<!-- 支持如下类型:
Advisor
MethodInterceptor (MethodInterceptor extends Advice)
MethodBeforeAdvice
AfterReturningAdvice
ThrowsAdvice
-->
<value>logAdviceXml</value>
</list>
</property>
</bean>
beanNames
支持正则 — 通过重写getAdvicesAndAdvisorsForBean
,匹配beanNames
,来判断是否支持拦截。interceptorNames
必须满足xml中的五种类型. – 在后续createProxy ---- 创建代理类
时,调用buildAdvisors
方法会使用interceptorNames
DefaultAdvisorAutoProxyCreator
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator">
<property name="usePrefix" value="true"/>
<!-- 容器中所有beanNamePrefix为"advisor", 且为Advisor-->
<property name="advisorBeanNamePrefix" value="advisor"></property>
</bean>
<bean id="advisor1" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="pattern">
<value>.*.*</value> <!-- 业务实现方法名匹配 -->
</property>
<property name="advice">
<!-- 必须是Advice子类,-->
<ref bean="logAdviceXml"/>
</property>
</bean>
createProxy — 创建代理类
//org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator
protected Object createProxy(
Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
//是否配置了proxy-target-class || BeanDefinition是否配置了preserveTargetClass 属性
if (!shouldProxyTargetClass(beanClass, beanName)) {
Class<?>[] targetInterfaces = ClassUtils.getAllInterfacesForClass(beanClass, this.proxyClassLoader);
for (Class<?> targetInterface : targetInterfaces) {
//添加代理接口
proxyFactory.addInterface(targetInterface);
}
}
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
for (Advisor advisor : advisors) {
//添加 advisors
proxyFactory.addAdvisor(advisor);
}
//设置要代理的类
proxyFactory.setTargetSource(targetSource);
//指定代理类
customizeProxyFactory(proxyFactory);
//默认值为false
//表示 由代理工厂配置后,是否还允许修改
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
//1.创建代理,并返回
return proxyFactory.getProxy(this.proxyClassLoader);
}
1. buildAdvisors()
//org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator
protected Advisor[] buildAdvisors(String beanName, Object[] specificInterceptors) {
//1.1 resolveInterceptorNames
Advisor[] commonInterceptors = resolveInterceptorNames();
List<Object> allInterceptors = new ArrayList<Object>();
if (specificInterceptors != null) {
allInterceptors.addAll(Arrays.asList(specificInterceptors));
if (commonInterceptors != null) {
if (this.applyCommonInterceptorsFirst) {
allInterceptors.addAll(0, Arrays.asList(commonInterceptors));
} else {
allInterceptors.addAll(Arrays.asList(commonInterceptors));
}
}
}
Advisor[] advisors = new Advisor[allInterceptors.size()];
for (int i = 0; i < allInterceptors.size(); i++) {
advisors[i] = this.advisorAdapterRegistry.wrap(allInterceptors.get(i));
}
return advisors;
}
//1.1 全局拦截器
private Advisor[] resolveInterceptorNames() {
ConfigurableBeanFactory cbf = (this.beanFactory instanceof ConfigurableBeanFactory) ?
(ConfigurableBeanFactory) this.beanFactory : null;
List<Advisor> advisors = new ArrayList<Advisor>();
//使用BeanNameAutoProxyCreator时,可以设置 interceptorNames
for (String beanName : this.interceptorNames) {
if (cbf == null || !cbf.isCurrentlyInCreation(beanName)) {
Object next = this.beanFactory.getBean(beanName);
//1.2 advisorAdapterRegistry = new DefaultAdvisorAdapterRegistry()
advisors.add(this.advisorAdapterRegistry.wrap(next));
}
}
return advisors.toArray(new Advisor[advisors.size()]);
}
//org.springframework.aop.framework.adapter.DefaultAdvisorAdapterRegistry
public class DefaultAdvisorAdapterRegistry implements AdvisorAdapterRegistry, Serializable {
private final List<AdvisorAdapter> adapters = new ArrayList<AdvisorAdapter>(3);
public DefaultAdvisorAdapterRegistry() {
registerAdvisorAdapter(new MethodBeforeAdviceAdapter());
registerAdvisorAdapter(new AfterReturningAdviceAdapter());
registerAdvisorAdapter(new ThrowsAdviceAdapter());
}
//仅支持 MethodInterceptor, Advisor
//MethodBeforeAdvice,AfterReturningAdvice,ThrowsAdvice类型
public Advisor wrap(Object adviceObject) throws UnknownAdviceTypeException {
if (adviceObject instanceof Advisor) {
return (Advisor) adviceObject;
}
if (!(adviceObject instanceof Advice)) {
throw new UnknownAdviceTypeException(adviceObject);
}
Advice advice = (Advice) adviceObject;
if (advice instanceof MethodInterceptor) {
// So well-known it doesn't even need an adapter.
return new DefaultPointcutAdvisor(advice);
}
for (AdvisorAdapter adapter : this.adapters) {
// Check that it is supported.
if (adapter.supportsAdvice(advice)) {
return new DefaultPointcutAdvisor(advice);
}
}
throw new UnknownAdviceTypeException(advice);
}
}
2.创建代理 – factory.createAopProxy()
在分析代码之前,我们先观察下ProxyFactory
的类图:
接着分析上述代码,proxyFactory.getProxy
逻辑如下:
//org.springframework.aop.framework.ProxyFactory
public class ProxyFactory extends ProxyCreatorSupport {
public Object getProxy(ClassLoader classLoader) {
//1.createAopProxy()
//2.getProxy
return createAopProxy().getProxy(classLoader);
}
//1.创建Proxy
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
activate();
}
//1.1 getAopProxyFactory()由父类ProxyCreatorSupport实现,返回DefaultAopProxyFactory
//1.2 最终调用:DefaultAopProxyFactory.createAopProxy
return getAopProxyFactory().createAopProxy(this);
}
}
//org.springframework.aop.framework.ProxyCreatorSupport
public class ProxyCreatorSupport extends AdvisedSupport {
private AopProxyFactory aopProxyFactory;
public ProxyCreatorSupport() {
this.aopProxyFactory = new DefaultAopProxyFactory();
}
//1.1
public AopProxyFactory getAopProxyFactory() {
return this.aopProxyFactory;
}
}
//org.springframework.aop.framework.DefaultAopProxyFactory
public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {
//1.2
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
//optimize: 使用cglib代理,激进化策略(不建议配置)
//proxyTargetClass : 是否使用了<aop:aspectj-autoproxy proxy-target-class="true" />
//hasNoUserSuppliedProxyInterfaces: 是否没有实现了接口(未实现返回true)
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()) {
return new JdkDynamicAopProxy(config);
}
return CglibProxyFactory.createCglibProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}
}
3. new、获取、执行代理
代理模式的详细介绍,可以翻阅下之前的总结:java代理模式
- jdk动态代理本质上是执行:
InvocationHandler.invoke
- cglib动态代理本质上是执行两种方式:
MethodInterceptor.intercept
—Spring cglib使用此种方法net.sf.cglib.proxy.InvocationHandler.invoke
3.1 JdkDynamicAopProxy
//org.springframework.aop.framework.JdkDynamicAopProxy
final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {
private final AdvisedSupport advised;
//代理接口中 有没有定义 equals 方法
private boolean equalsDefined;
//代理接口中 有没有定义 hashCode 方法
private boolean hashCodeDefined;
//a. new代理
public JdkDynamicAopProxy(AdvisedSupport config) throws AopConfigException {
this.advised = config;
}
//b. 获取代理
public Object getProxy() {
return getProxy(ClassUtils.getDefaultClassLoader());
}
public Object getProxy(ClassLoader classLoader) {
//获取 代理的接口数组
//判断是否添加SpringProxy 和 Advised接口
Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised);
//遍历 代理的接口中是否定义了equals和hashCode方法;
findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
//this 即 JdkDynamicAopProxy 实现了 InvocationHandler
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}
//c.执行代理
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
MethodInvocation invocation;
Object oldProxy = null;
boolean setProxyContext = false;
TargetSource targetSource = this.advised.targetSource;
Class<?> targetClass = null;
Object target = null;
try {
//如果是 equals,hashCode,opaque等方法 略...
Object retVal;
if (this.advised.exposeProxy) {
//用来解决,Aop代理失效问题
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
target = targetSource.getTarget();
if (target != null) {
targetClass = target.getClass();
}
//1. 获取当前方法的 拦截器链(列表) : IntroductionAdvisor + PointcutAdvisor
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
if (chain.isEmpty()) {
//没有匹配到拦截的 直接调用target执行原方法
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, args);
} else {
//2. 将 Advice列表 封装为MethodInvocation
invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
//3. 执行拦截器链
retVal = invocation.proceed();
}
Class<?> returnType = method.getReturnType();
if (retVal != null && retVal == target && returnType.isInstance(proxy) &&
!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
//如果返回对象为: this ,特殊处理
retVal = proxy;
}
return retVal;
} finally {
if (target != null && !targetSource.isStatic()) {
// SingletonTargetSource.releaseTarget() --- 空处理
targetSource.releaseTarget(target);
}
if (setProxyContext) {
//每次执行invoke结束时,最终都要restore oldProxy
AopContext.setCurrentProxy(oldProxy);
}
}
}
//@Override equals ,hashCode 略
}
3.2 CglibDynamicAopProxy
//org.springframework.aop.framework.CglibAopProxy
final class CglibAopProxy implements AopProxy, Serializable {
//略.....
/** 缓存已经校验过的classes */
private static final Map<Class<?>, Boolean> validatedClasses = new WeakHashMap<Class<?>, Boolean>();
protected final AdvisedSupport advised;
private final transient AdvisedDispatcher advisedDispatcher;
//a. new 代理
public CglibAopProxy(AdvisedSupport config) throws AopConfigException {
this.advised = config;
this.advisedDispatcher = new AdvisedDispatcher(this.advised);
}
//b. 获取代理
public Object getProxy() {
return getProxy(null);
}
public Object getProxy(ClassLoader classLoader) {
Class<?> rootClass = this.advised.getTargetClass();
Class<?> proxySuperClass = rootClass;
//rootClassName是否包含$$
if (ClassUtils.isCglibProxyClass(rootClass)) {
//获取rootClass父类,设置为proxySuperClass
proxySuperClass = rootClass.getSuperclass();
//此时的rootClass额外implements了若干接口,需要添加到advised中
Class<?>[] additionalInterfaces = rootClass.getInterfaces();
for (Class<?> additionalInterface : additionalInterfaces) {
this.advised.addInterface(additionalInterface);
}
}
//校验class,如果存在 (not Object.clas && !static && final 方法,log.warn())
validateClassIfNecessary(proxySuperClass);
// 创建new Enhancer();
Enhancer enhancer = createEnhancer();
enhancer.setSuperclass(proxySuperClass);
enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
enhancer.setStrategy(new MemorySafeUndeclaredThrowableStrategy(UndeclaredThrowableException.class));
enhancer.setInterceptDuringConstruction(false);
//获取拦截链
Callback[] callbacks = getCallbacks(rootClass);
//略.....
enhancer.setCallbacks(callbacks);
// 生成proxySuperClass子类,并创建实例
Object proxy;
if (this.constructorArgs != null) {
proxy = enhancer.create(this.constructorArgTypes, this.constructorArgs);
} else {
proxy = enhancer.create();
}
return proxy;
}
private Callback[] getCallbacks(Class<?> rootClass) throws Exception {
boolean exposeProxy = this.advised.isExposeProxy();
boolean isFrozen = this.advised.isFrozen();
//是否静态目标:即是否为静态类
boolean isStatic = this.advised.getTargetSource().isStatic();
//将aop的拦截链,封装在DynamicAdvisedInterceptor中
Callback aopInterceptor = new DynamicAdvisedInterceptor(this.advised);
Callback[] mainCallbacks = new Callback[] {
aopInterceptor, // 将aop的拦截链加入mainCallbacks
targetInterceptor, // invoke target without considering advice, if optimized
new SerializableNoOp(), // no override for methods mapped to this
targetDispatcher, this.advisedDispatcher,
new EqualsInterceptor(this.advised),
new HashCodeInterceptor(this.advised)
};
Callback[] callbacks;
//略.....
callbacks = mainCallbacks;
return callbacks;
}
//实现了MethodInterceptor 接口
private static class DynamicAdvisedInterceptor implements MethodInterceptor, Serializable {
private final AdvisedSupport advised;
public DynamicAdvisedInterceptor(AdvisedSupport advised) {
this.advised = advised;
}
//调用MethodInterceptor.intercept 执行
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
Object oldProxy = null;
boolean setProxyContext = false;
Class<?> targetClass = null;
Object target = null;
try {
if (this.advised.exposeProxy) {
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
target = getTarget();
if (target != null) {
targetClass = target.getClass();
}
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
Object retVal;
if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
//直接执行原始方法
retVal = methodProxy.invoke(target, args);
}else {
//CglibMethodInvocation 继承 CglibMethodInvocation,并未重写proceed()
retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
}
//特殊处理返回值为this的情况.....
retVal = processReturnType(proxy, target, method, retVal);
return retVal;
} finally {
if (target != null) {
releaseTarget(target);
}
if (setProxyContext) {
AopContext.setCurrentProxy(oldProxy);
}
}
}
}
//c. 执行代理(略...)
public Object invoke(Object proxy, Method method, Object[] args) {
}