基础定义:
- Pointcut:切点
- Advice:通知或增强,织入逻辑存在的地方
- Advisor:通知器,可以将切点与通知相结合。
简单demo:
github
接口TestServiceI
public interface TestServiceI {
void method1();
void method2();
}
接口实现类TestServiceA
@Service
public class TestServiceA implements TestServiceI {
@Override
public void method1() {
System.out.println("TestServiceA method1...");
}
@Override
public void method2() {
System.out.println("TestServiceA method2...");
}
}
另一个没有实现接口的ServiceTestServiceB
@Service
public class TestServiceB {
public void method1() {
System.out.println("TestServiceB method1...");
}
}
通知类MyAdvice
@Component
public class MyAdvice implements MethodBeforeAdvice, AfterReturningAdvice {
@Override
public void before(Method method, Object[] args, Object target) {
System.out.println("before...");
}
@Override
public void afterReturning(Object returnValue, Method method, Object[] args, Object target) {
System.out.println("after...");
}
}
Aop配置AopConfiguration
@Configuration
public class AopConfiguration {
@Autowired
private TestServiceA testServiceA;
@Autowired
private TestServiceB testServiceB;
@Bean
public ProxyFactoryBean proxyFactoryBeanA() throws ClassNotFoundException {
ProxyFactoryBean proxyFactoryBean = new ProxyFactoryBean();
proxyFactoryBean.setProxyInterfaces(new Class[]{TestServiceI.class});
proxyFactoryBean.setTarget(testServiceA);
proxyFactoryBean.setInterceptorNames("myAdvice");
return proxyFactoryBean;
}
@Bean
public ProxyFactoryBean proxyFactoryBeanB() {
ProxyFactoryBean proxyFactoryBean = new ProxyFactoryBean();
proxyFactoryBean.setTarget(testServiceB);
proxyFactoryBean.setInterceptorNames("myAdvice");
return proxyFactoryBean;
}
}
运行Aop test1
public class Aop {
@Test
public void test1() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext("com.tianwen.spring");
TestServiceI testServiceA = (TestServiceI) context.getBean("proxyFactoryBeanA");
testServiceA.method1();
System.out.println("---");
testServiceA.method2();
System.out.println("---");
TestServiceB testServiceB = (TestServiceB) context.getBean("proxyFactoryBeanB");
testServiceB.method1();
}
}
运行结果:
before...
TestServiceA method1...
after...
---
before...
TestServiceA method2...
after...
---
before...
TestServiceB method1...
after...
TestServiceA
在AopConfiguration
中配置了代理接口,故代理类由JDK生成,TestServiceB
的代理类由Cglib生成。
代理类的生成过程:
ProxyFactoryBean
是FactoryBean
查看getObject()
方法。
public class ProxyFactoryBean extends ProxyCreatorSupport
implements FactoryBean
GlobalAdvisorAdapterRegistry getInstance()
方法
public abstract class GlobalAdvisorAdapterRegistry {
...
// 顺序5
// 再来看DefaultAdvisorAdapterRegistry
private static AdvisorAdapterRegistry instance = new DefaultAdvisorAdapterRegistry();
...
// 顺序4
public static AdvisorAdapterRegistry getInstance() {
return instance;
}
DefaultAdvisorAdapterRegistry
public class DefaultAdvisorAdapterRegistry implements AdvisorAdapterRegistry, Serializable {
private final List adapters = new ArrayList(3);
// 顺序5
// 构造器 前置、后置和异常通知适配器
public DefaultAdvisorAdapterRegistry() {
registerAdvisorAdapter(new MethodBeforeAdviceAdapter());
registerAdvisorAdapter(new AfterReturningAdviceAdapter());
registerAdvisorAdapter(new ThrowsAdviceAdapter());
}
// 顺序6
@Override
public Advisor wrap(Object adviceObject) throws UnknownAdviceTypeException {
// 如果容器中的bean已经是通知器 返回
if (adviceObject instanceof Advisor) {
return (Advisor) adviceObject;
}
if (!(adviceObject instanceof Advice)) {
throw new UnknownAdviceTypeException(adviceObject);
}
// 强转为通知
Advice advice = (Advice) adviceObject;
// 如果通知实现MethodInterceptor接口,不需要适配器,返回默认切点通知器(DefaultPointcutAdvisor)
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);
}
}
// 回到顺序3
throw new UnknownAdviceTypeException(advice);
}
AdvisedSupport
public class AdvisedSupport extends ProxyConfig implements Advised {
...
private List> interfaces = new ArrayList>();
...
private List advisors = new LinkedList();
private Advisor[] advisorArray = new Advisor[0];
...
private List advisors = new LinkedList();
...
// 顺序7
@Override
public void addAdvisor(Advisor advisor) {
int pos = this.advisors.size();
// 顺序8
addAdvisor(pos, advisor);
}
// 顺序8
@Override
public void addAdvisor(int pos, Advisor advisor) throws AopConfigException {
// 通知器为DefaultPointcutAdvisor,false
if (advisor instanceof IntroductionAdvisor) {
validateIntroductionAdvisor((IntroductionAdvisor) advisor);
}
// 顺序9
addAdvisorInternal(pos, advisor);
}
...
// 顺序9
private void addAdvisorInternal(int pos, Advisor advisor) throws AopConfigException {
Assert.notNull(advisor, "Advisor must not be null");
if (isFrozen()) {
throw new AopConfigException("Cannot add advisor: Configuration is frozen.");
}
if (pos > this.advisors.size()) {
throw new IllegalArgumentException(
"Illegal position " + pos + " in advisor list with size " + this.advisors.size());
}
// 添加到list中,至此完成初始化通知器链,再回到ProxyFactoryBean的getObject()中。
this.advisors.add(pos, advisor);
// 更新到advisorArray属性中
updateAdvisorArray();
adviceChanged();
// 回到顺序1
}
...
// 在构造ProxyFactoryBean时,调用setProxyInterfaces()方法设置代理接口时,实际调用了基类的setInterfaces方法,将代理的接口保存在当前类的interfaces属性中
public void setInterfaces(Class>... interfaces) {
Assert.notNull(interfaces, "Interfaces must not be null");
this.interfaces.clear();
for (Class> ifc : interfaces) {
addInterface(ifc);
}
}
public void addInterface(Class> intf) {
Assert.notNull(intf, "Interface must not be null");
if (!intf.isInterface()) {
throw new IllegalArgumentException("[" + intf.getName() + "] is not an interface");
}
if (!this.interfaces.contains(intf)) {
this.interfaces.add(intf);
adviceChanged();
}
}
...
// 返回变量interfaces中的接口
@Override
public Class>[] getProxiedInterfaces() {
return this.interfaces.toArray(new Class>[this.interfaces.size()]);
}
ProxyCreatorSupport
public class ProxyCreatorSupport extends AdvisedSupport {
...
public ProxyCreatorSupport() {
// 顺序13
this.aopProxyFactory = new DefaultAopProxyFactory();
}
...
// 顺序12
public AopProxyFactory getAopProxyFactory() {
// 顺序13
return this.aopProxyFactory;
}
...
// 顺序11
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
activate();
}
// AopProxyFactory为DefaultAopProxyFactory,由它负责创建Aop代理
// 顺序12 顺序14
return getAopProxyFactory().createAopProxy(this);
}
DefaultAopProxyFactory
public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {
// 顺序14
@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)) {
return new JdkDynamicAopProxy(config);
}
// 返回使用Cglib代理ObjenesisCglibAopProxy
return new ObjenesisCglibAopProxy(config);
}
// 如果没有设置代理接口,返回使用Jdk代理JdkDynamicAopProxy
else {
return new JdkDynamicAopProxy(config);
}
// 回到顺序11
}
private boolean hasNoUserSuppliedProxyInterfaces(AdvisedSupport config) {
// AdvisedSupport的getProxiedInterfaces()方法
Class>[] ifcs = config.getProxiedInterfaces();
return (ifcs.length == 0 || (ifcs.length == 1 && SpringProxy.class.isAssignableFrom(ifcs[0])));
}
CglibAopProxy getProxy()
class CglibAopProxy implements AopProxy, Serializable {
...
@Override
// 顺序16
public Object getProxy(ClassLoader classLoader) {
if (logger.isDebugEnabled()) {
logger.debug("Creating CGLIB proxy: target source is " + this.advised.getTargetSource());
}
try {
Class> rootClass = this.advised.getTargetClass();
Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");
Class> proxySuperClass = rootClass;
if (ClassUtils.isCglibProxyClass(rootClass)) {
proxySuperClass = rootClass.getSuperclass();
Class>[] additionalInterfaces = rootClass.getInterfaces();
for (Class> additionalInterface : additionalInterfaces) {
this.advised.addInterface(additionalInterface);
}
}
// Validate the class, writing log messages as necessary.
validateClassIfNecessary(proxySuperClass, classLoader);
// Configure CGLIB Enhancer...
// 构造CGLIB Enhancer
Enhancer enhancer = createEnhancer();
if (classLoader != null) {
enhancer.setClassLoader(classLoader);
if (classLoader instanceof SmartClassLoader &&
((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
enhancer.setUseCache(false);
}
}
enhancer.setSuperclass(proxySuperClass);
enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
enhancer.setStrategy(new ClassLoaderAwareUndeclaredThrowableStrategy(classLoader));
// 顺序17
// 回调方法
Callback[] callbacks = getCallbacks(rootClass);
Class>[] types = new Class>[callbacks.length];
for (int x = 0; x < types.length; x++) {
types[x] = callbacks[x].getClass();
}
// fixedInterceptorMap only populated at this point, after getCallbacks call above
enhancer.setCallbackFilter(new ProxyCallbackFilter(
this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
enhancer.setCallbackTypes(types);
// Generate the proxy class and create a proxy instance.
return createProxyClassAndInstance(enhancer, callbacks);
}
catch (CodeGenerationException ex) {
throw new AopConfigException("Could not generate CGLIB subclass of class [" +
this.advised.getTargetClass() + "]: " +
"Common causes of this problem include using a final class or a non-visible class",
ex);
}
catch (IllegalArgumentException ex) {
throw new AopConfigException("Could not generate CGLIB subclass of class [" +
this.advised.getTargetClass() + "]: " +
"Common causes of this problem include using a final class or a non-visible class",
ex);
}
catch (Throwable ex) {
// TargetSource.getTarget() failed
throw new AopConfigException("Unexpected AOP exception", ex);
}
}
...
// 顺序17
private Callback[] getCallbacks(Class> rootClass) throws Exception {
// Parameters used for optimization choices...
boolean exposeProxy = this.advised.isExposeProxy();
boolean isFrozen = this.advised.isFrozen();
boolean isStatic = this.advised.getTargetSource().isStatic();
// Choose an "aop" interceptor (used for AOP calls).
// 使用内部类 DynamicAdvisedInterceptor作为回调
Callback aopInterceptor = new DynamicAdvisedInterceptor(this.advised);
// Choose a "straight to target" interceptor. (used for calls that are
// unadvised but can return this). May be required to expose the proxy.
Callback targetInterceptor;
if (exposeProxy) {
targetInterceptor = isStatic ?
new StaticUnadvisedExposedInterceptor(this.advised.getTargetSource().getTarget()) :
new DynamicUnadvisedExposedInterceptor(this.advised.getTargetSource());
}
else {
targetInterceptor = isStatic ?
new StaticUnadvisedInterceptor(this.advised.getTargetSource().getTarget()) :
new DynamicUnadvisedInterceptor(this.advised.getTargetSource());
}
// Choose a "direct to target" dispatcher (used for
// unadvised calls to static targets that cannot return this).
Callback targetDispatcher = isStatic ?
new StaticDispatcher(this.advised.getTargetSource().getTarget()) : new SerializableNoOp();
Callback[] mainCallbacks = new Callback[] {
aopInterceptor, // for normal advice
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;
// If the target is a static one and the advice chain is frozen,
// then we can make some optimizations by sending the AOP calls
// direct to the target using the fixed chain for that method.
if (isStatic && isFrozen) {
Method[] methods = rootClass.getMethods();
Callback[] fixedCallbacks = new Callback[methods.length];
this.fixedInterceptorMap = new HashMap(methods.length);
// TODO: small memory optimization here (can skip creation for methods with no advice)
for (int x = 0; x < methods.length; x++) {
List
JdkDynamicAopProxy getProxy()
final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {
...
// 顺序18
@Override
public Object getProxy(ClassLoader classLoader) {
if (logger.isDebugEnabled()) {
logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource());
}
Class>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
// JDK的Proxy类,InvocationHandler为JdkDynamicAopProxy。可以看到JdkDynamicAopProxy有实现InvocationHandler接口
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}
至此,代理对象已经创建完毕。下一篇分析调用代理对象对应方法时,织入的逻辑如何工作。