动态代理:https://github.com/helloallworld/myboot152.git我自己写的demo里有一点点说明
基础概念:(概括,具体的百度下)
Pointcut:切点,表明哪些类的哪些方法需要调用相应的通知
Advice:通知,包括before(切点执行前),after(后),around(环绕)等,表明在执行切点的时候调用额外的逻辑。
aspect(Advisor):切面,将切点和通知联系起来
target:需要做AOP的目标类,即:切点中表明的那些类
ProxyFactoryBean:AOP代理factoryBean(AOP实现核心,第一次创建target类时最后会跳到ProxyFactoryBean.getObject里)
proxyFactoryBean extends AdvisedSupport ; AdvisedSupport extends AdvisedSupport ;AdvisedSupport中存了Advice链,advisor切面等相关的信息,供其子类使用。AdvisedSupport extends ProxyConfig;ProxyConfig中有一些控制属性,主要控制如何创建代理
当从context中获取target时
TestTarge targe=(TestTarge) context.getBean("testTarge");==============>AbstractApplicationContext.getBean()
===============>AbstractBeanFactory.getBean();==================>AbstractBeanFactory.doGetBean();=============>AbstractBeanFactory.getObjectForBeanInstance();==========第一次创建该Bean时,会将ProxyFactoryBean放进去===========>FactoryBeanRegistrySupport.getObjectFromFactoryBean(FactoryBean<?>factory,String beanName,boolean shouldPostProcess)==============>FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBean factory,String beanName);================>factory.getObject();此时会跳到===============>ProxyFactoryBean.getObject();这个方法中会调用 initializeAdvisorChain() ;他会创建与该bean相关的advisor等。
ProxyFactoryBean.getObject()方法
/**
* Return a proxy. Invoked when clients obtain beans from this factory bean.
* Create an instance of the AOP proxy to be returned by this factory.
* The instance will be cached for a singleton, and create on each call to
* {@code getObject()} for a proxy.
* @return a fresh AOP proxy reflecting the current state of this factory
返回一个由本Factory(ProxyFactoryBean)创建的一个AOP代理的示例
*/
@Override
public Object getObject() throws BeansException {
//创建advisor链(即切面相关的通知,切点等)
initializeAdvisorChain();
if (isSingleton()) {
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();
}
}
initializeAdvisorChain()方法:创建advisor(切面)链
/**
* Create the advisor (interceptor) chain. Advisors that are sourced
* from a BeanFactory will be refreshed each time a new prototype instance
* is added. Interceptors added programmatically through the factory API
* are unaffected by such changes.
*/
//创建切面(拦截)链,每次有新更改都会重新加载。
private synchronized void initializeAdvisorChain() throws AopConfigException, BeansException {
//已加创建过,不再创建
if (this.advisorChainInitialized) {
return;
}
//interceptorNames是切面name组成的数组
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.
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");
}
//将指定路径下的都加入到拦截链中,里面最后也调用了addAdvisorOnChainCreation(advice, name);
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.
//根据advisor的name获取真正的advisor(切面)/advice(通知)
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.
advice = new PrototypePlaceholderAdvisor(name);
}
//根据advisor(切面)信息,将该advisor增加到advisor链中
addAdvisorOnChainCreation(advice, name);
}
}
}
this.advisorChainInitialized = true;
}
getSingletonInstance()方法:指定aop代理来获取target单例代理实例
private synchronized Object getSingletonInstance() {
if (this.singletonInstance == null) {
//targetSource:需要做AOP的目标类,即:切点中表明的那些类
this.targetSource = freshTargetSource();
if (this.autodetectInterfaces && getProxiedInterfaces().length == 0 && !isProxyTargetClass()) {
// Rely on AOP infrastructure to tell us what interfaces to proxy.
//获取targetSource的 真正代理类
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);
/**creatAopProxy:创建AOP代理类,有JdkDynamicAopProxy和CglibAopProxy代理方式。
*creatAopProxy就是确定具体使用哪种代理方式创建所需的target实例
*/
this.singletonInstance = getProxy(createAopProxy());
}
return this.singletonInstance;
}
getProxy()方法:最后会指向JdkDynamicAopProxy或者CglibAopProxy两个中的getProxy;这里面用到了JAVA的动态代理模式
JdkDynamicAopProxy和CglibAopProxy两个类都implements InvocationHandler;InvocationHandler是动态代理的关键接口,实现了该接口的类有一个动态代理的关键方法invoke();该方法可以定义在 调用真正被代理的方法前后的操作
总结:在运行获取AOP代理过的实例时,会先对advisor链进行组装,把该链存在advisorArray属性中(AdvisedSupport中的属性,ProxyFactoryBean继承了该类),然后再去JdkDynamicAopProxy或者CglibAopProxy中创建动态代理类。在这两个类中的invoke()方法会对advisor链进行解析,加载