基础定义:
- Pointcut:切点
- Advice:通知或增强,织入逻辑存在的地方
- Advisor:通知器,可以将切点与通知相结合。
简单demo:
接口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<Object>, BeanClassLoaderAware, BeanFactoryAware {
...
public static final String GLOBAL_SUFFIX = "*";
...
private AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();
...
private transient BeanFactory beanFactory;
...
@Override
public Object getObject() throws BeansException {
// 顺序1
// 初始化通知器链
initializeAdvisorChain();
// 默认true
if (isSingleton()) {
// 顺序10
return getSingletonInstance();
}
else {
if (this.targetName == null) {
logger.warn("Using non-singleton proxies with singleton targets is often undesirable. " +
"Enable prototype proxies by setting the 'targetName' property.");
}
return newPrototypeInstance();
}
}
...
// 顺序1
private synchronized void initializeAdvisorChain() throws AopConfigException, BeansException {
// 是否已经初始化过
if (this.advisorChainInitialized) {
return;
}
// interceptorNames为数组。值为指定的通知或通知器在容器中的bean name。
// interceptorNames的值,是在使用ProxyFactoryBean时配置的
// 例如demo中的proxyFactoryBean.setInterceptorNames("myAdvice");
if (!ObjectUtils.isEmpty(this.interceptorNames)) {
if (this.beanFactory == null) {
throw new IllegalStateException("No BeanFactory available anymore (probably due to serialization) " +
"- cannot resolve interceptor names " + Arrays.asList(this.interceptorNames));
}
// Globals can't be last unless we specified a targetSource using the property...
if (this.interceptorNames[this.interceptorNames.length - 1].endsWith(GLOBAL_SUFFIX) &&
this.targetName == null && this.targetSource == EMPTY_TARGET_SOURCE) {
throw new AopConfigException("Target required after globals");
}
// Materialize interceptor chain from bean names.
// 根据bean name,具体化拦截器。
for (String name : this.interceptorNames) {
if (logger.isTraceEnabled()) {
logger.trace("Configuring advisor or advice '" + name + "'");
}
// 是否以*结尾
if (name.endsWith(GLOBAL_SUFFIX)) {
if (!(this.beanFactory instanceof ListableBeanFactory)) {
throw new AopConfigException(
"Can only use global advisors or interceptors with a ListableBeanFactory");
}
// 以*结尾添加全局通知器
addGlobalAdvisor((ListableBeanFactory) this.beanFactory,
name.substring(0, name.length() - GLOBAL_SUFFIX.length()));
}
else {
// If we get here, we need to add a named interceptor.
// We must check if it's a singleton or prototype.
Object advice;
// 当前通知为原型还是单例
if (this.singleton || this.beanFactory.isSingleton(name)) {
// Add the real Advisor/Advice to the chain.
// 单例 调用容器的getBean
// 当前ProxyFactoryBean有实现BeanFactoryAware接口,在setBeanFactory方法中通过回调可以拿到当前IOC容器,使用变量beanFactory接收。
// 此用法属于spring容器的高级特性
// 这里可以看出,需要将这些拦截器托管给容器。否则会找不到bean。
advice = this.beanFactory.getBean(name);
}
else {
// It's a prototype Advice or Advisor: replace with a prototype.
// Avoid unnecessary creation of prototype bean just for advisor chain initialization.
// 原型 new PrototypePlaceholderAdvisor
advice = new PrototypePlaceholderAdvisor(name);
}
// 顺序2
// 拿到通知后,将通知器添加到通知器链上
addAdvisorOnChainCreation(advice, name);
}
}
}
// 完成通知器初始化
this.advisorChainInitialized = true;
}
...
// 顺序2
private void addAdvisorOnChainCreation(Object next, String name) {
// 顺序3
// We need to convert to an Advisor if necessary so that our source reference
// matches what we find from superclass interceptors.
// 将容器中取得的bean转化为通知器
Advisor advisor = namedBeanToAdvisor(next);
if (logger.isTraceEnabled()) {
logger.trace("Adding advisor with name '" + name + "'");
}
// 顺序7
// 拿到通知器后,添加
// 基类AdvisedSupport中的方法
addAdvisor(advisor);
}
...
// 顺序3
private Advisor namedBeanToAdvisor(Object next) {
try {
// 顺序4 顺序6
// advisorAdapterRegistry被声明为GlobalAdvisorAdapterRegistry.getInstance();
return this.advisorAdapterRegistry.wrap(next);
}
catch (UnknownAdviceTypeException ex) {
// We expected this to be an Advisor or Advice,
// but it wasn't. This is a configuration error.
throw new AopConfigException("Unknown advisor type " + next.getClass() +
"; Can only include Advisor or Advice type beans in interceptorNames chain except for last entry," +
"which may also be target or TargetSource", ex);
}
}
...
@Override
public void setBeanFactory(BeanFactory beanFactory) {
this.beanFactory = beanFactory;
checkInterceptorNames();
}
...
// 顺序10
private synchronized Object getSingletonInstance() {
if (this.singletonInstance == null) {
this.targetSource = freshTargetSource();
if (this.autodetectInterfaces && getProxiedInterfaces().length == 0 && !isProxyTargetClass()) {
// Rely on AOP infrastructure to tell us what interfaces to proxy.
Class<?> targetClass = getTargetClass();
if (targetClass == null) {
throw new FactoryBeanNotInitializedException("Cannot determine target class for proxy");
}
setInterfaces(ClassUtils.getAllInterfacesForClass(targetClass, this.proxyClassLoader));
}
// Initialize the shared singleton instance.
super.setFrozen(this.freezeProxy);
// 顺序11,顺序15
// 先创建Aop代理,再根据创建的代理生成代理对象。
// 父类ProxyCreatorSupport中的createAopProxy()方法
this.singletonInstance = getProxy(createAopProxy());
}
// 返回创建的代理对象
return this.singletonInstance;
}
...
// 顺序15
protected Object getProxy(AopProxy aopProxy) {
// 顺序16 顺序18
// 分别对应最下面的JdkDynamicAopProxy与CglibAopProxy的getProxy方法
return aopProxy.getProxy(this.proxyClassLoader);
}
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<AdvisorAdapter> adapters = new ArrayList<AdvisorAdapter>(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<Class<?>> interfaces = new ArrayList<Class<?>>();
...
private List<Advisor> advisors = new LinkedList<Advisor>();
private Advisor[] advisorArray = new Advisor[0];
...
private List<Advisor> advisors = new LinkedList<Advisor>();
...
// 顺序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<String, Integer>(methods.length);
// TODO: small memory optimization here (can skip creation for methods with no advice)
for (int x = 0; x < methods.length; x++) {
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(methods[x], rootClass);
fixedCallbacks[x] = new FixedChainStaticTargetInterceptor(
chain, this.advised.getTargetSource().getTarget(), this.advised.getTargetClass());
this.fixedInterceptorMap.put(methods[x].toString(), x);
}
// Now copy both the callbacks from mainCallbacks
// and fixedCallbacks into the callbacks array.
callbacks = new Callback[mainCallbacks.length + fixedCallbacks.length];
System.arraycopy(mainCallbacks, 0, callbacks, 0, mainCallbacks.length);
System.arraycopy(fixedCallbacks, 0, callbacks, mainCallbacks.length, fixedCallbacks.length);
this.fixedInterceptorOffset = mainCallbacks.length;
}
else {
callbacks = mainCallbacks;
}
return callbacks;
}
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);
}
至此,代理对象已经创建完毕。下一篇分析调用代理对象对应方法时,织入的逻辑如何工作。