spring的aop
bean的层级结构,这个图是从网上贴过来的↓
好吧,图没了,就这样吧,就是个bean创建时候各个类的继承实现关系图。翻一翻源码就知道了,这里就不画图了。基类是BeanFactory。
首先是创建bean。嗯。
调用applyBeanPostProcessorsAfterInitialization
然后呢,调用postProcessBeforeInstantiation方法
然后呢,调用postProcessAfterInitialization方法,处理一下实例化之后的事情,很明确,这名字真好。
然后咧,会调用wrapIfNecessary这个判断。
然后就各种判断啦,比如:对,我们想要知道的,要不要加代理。
里面会有一行代码注释:
// Create proxy if we have advice.
这个注释真的是超棒!一眼就看见了。
接下来就是实现抽象类的方法了:getAdvicesAndAdvisorsForBean
这个啊,然后往这个方法里面走一走,会发现它调用了BeanFactoryAdvisorRetrievalHelper的findAdvisorBeans。
然后如果可以创建代理,会返回一个数组。
创建代理的方法呢,源码在这里:
protected Object createProxy(
Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {
ProxyFactory proxyFactory = new ProxyFactory();
// Copy our properties (proxyTargetClass etc) inherited from ProxyConfig.
proxyFactory.copyFrom(this);
if (!shouldProxyTargetClass(beanClass, beanName)) {
// Must allow for introductions; can't just set interfaces to
// the target's interfaces only.
// ==> 这里有个类加载器
Class<?>[] targetInterfaces = ClassUtils.getAllInterfacesForClass(beanClass, this.proxyClassLoader);
// ==> 然后这个就放到代理工厂对象里去了
for (Class<?> targetInterface : targetInterfaces) {
proxyFactory.addInterface(targetInterface);
}
}
// specificInterceptors 这个是 TransactionInterceptor,事务拦截器,配置文件
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
for (Advisor advisor : advisors) {
proxyFactory.addAdvisor(advisor);
}
proxyFactory.setTargetSource(targetSource);
customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
return proxyFactory.getProxy(this.proxyClassLoader);
}
proxy的方法如下:
public Object getProxy(ClassLoader classLoader) {
return createAopProxy().getProxy(classLoader);
}
然后就会调用这个方法:
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) { // hasNoUserSuppliedProxyInterfaces确定提供的AdvisedSupport是否只指定了SpringProxy接口(或者根本没有指定代理接口)。
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);
}
if (!cglibAvailable) {
throw new AopConfigException(
"Cannot proxy target class because CGLIB2 is not available. " +
"Add CGLIB to the class path or specify proxy interfaces.");
}
return CglibProxyFactory.createCglibProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}
这两个属性都可以配置:optimize如果是true,则表示用jdk的动态代理;proxyTargetClass如果是true,则表示用jdk的动态代理。否则用Cglib代理。
嗯。这边就结束了。
然后我们看引入的aop的xsd文件中有如下配置:
<xsd:element name="aspectj-autoproxy">
<xsd:annotation>
<xsd:documentation source="java:org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator"><![CDATA[
Enables the use of the @AspectJ style of Spring AOP.
]]></xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:sequence>
<xsd:element name="include" type="includeType" minOccurs="0" maxOccurs="unbounded">
<xsd:annotation>
<xsd:documentation><![CDATA[
Indicates that only @AspectJ beans with names matched by the (regex)
pattern will be considered as defining aspects to use for Spring autoproxying.
]]></xsd:documentation>
</xsd:annotation>
</xsd:element>
</xsd:sequence>
<xsd:attribute name="proxy-target-class" type="xsd:boolean" default="false">
<xsd:annotation>
<xsd:documentation><![CDATA[
Are class-based (CGLIB) proxies to be created? By default, standard
Java interface-based proxies are created.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="expose-proxy" type="xsd:boolean" default="false">
<xsd:annotation>
<xsd:documentation><![CDATA[
Indicate that the proxy should be exposed by the AOP framework as a
ThreadLocal for retrieval via the AopContext class. Off by default,
i.e. no guarantees that AopContext access will work.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
表明调用的是AnnotationAwareAspectJAutoProxyCreator类。
这个类里呢有这样的方法:
@Override
protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
super.initBeanFactory(beanFactory);
this.aspectJAdvisorsBuilder =
new BeanFactoryAspectJAdvisorsBuilderAdapter(beanFactory, this.aspectJAdvisorFactory);
}
@Override
protected boolean isInfrastructureClass(Class beanClass) {
// Previously we setProxyTargetClass(true) in the constructor, but that has too
// broad an impact. Instead we now override isInfrastructureClass to avoid proxying
// aspects. I'm not entirely happy with that as there is no good reason not
// to advise aspects, except that it causes advice invocation to go through a
// proxy, and if the aspect implements e.g the Ordered interface it will be
// proxied by that interface and fail at runtime as the advice method is not
// defined on the interface. We could potentially relax the restriction about
// not advising aspects in the future.
// aspectJAdvisorFactory就在这里~
return (super.isInfrastructureClass(beanClass) || this.aspectJAdvisorFactory.isAspect(beanClass));
}
而这个类呢,AbstractAdvisorAutoProxyCreator是这个类的超类,重写了AbstractAutoProxyCreator的诸多方法。
AbstractAutoProxyCreator的postProcessBeforeInstantiation里呢,还有这个方法:createProxy
首先调用的是BeanFactoryAspectJAdvisorsBuilder的buildAspectJAdvisors,获取所有beanNames,然后判断class上是否有aspect注解,如果有并且方法名没有“ajc$”,说明是需要代理的。这个判断是在AbstractAspectJAdvisorFactory里,常量名字叫:AJC_MAGIC,是不是很神奇?又是一个很棒的名字。(∩_∩)
ajc$呢,是将切面编译进字节码带上的前缀,很有趣。
主要就是 postProcessBeforeInstantiation方法 和 postProcessAfterInitialization方法,这两个处理方法。