最基本的使用,在建立了業務接口和實現類後,經過配置<aop:config>....</aop:config>
標籤來指定<aop:pointcut
和<aop:advisor
。示例以下:php
接口:java
public interface MockService {
public String hello(String s);
}
複製代碼
實現類:spring
public class MockServiceImpl implements MockService {
@Override
public String hello(String s) {
System.out.println("execute hello");
return s;
}
}
複製代碼
實現接口org.aopalliance.intercept.MethodInterceptor
express
public class CustomInterceptor implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.println("CustomInterceptor before");
Object result = invocation.proceed();
System.out.println("CustomInterceptor after");
return result;
}
}
複製代碼
建立aop.xml
,放在resources目錄下:數組
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd" default-lazy-init="false" default-autowire="byName">
<!-- 實現來org.aopalliance.intercept.MethodInterceptor的攔截器 -->
<bean id="customInterceptor" class="com.xxx.yyy.CustomInterceptor"/>
<bean id="mockService" class="com.xxx.yyy.MockServiceImpl"/>
<aop:config proxy-target-class="true">
<aop:pointcut id="interceptorPointCuts" expression="execution(* com.xxx.yyy..*.*(..))"/>
<aop:advisor advice-ref="customInterceptor" pointcut-ref="interceptorPointCuts"/>
</aop:config>
</beans>
複製代碼
public class Main {
public static void main(String[] args){
ApplicationContext context = new ClassPathXmlApplicationContext("aop.xml");
MockService mockService = (MockService) context.getBean("mockService");
mockService.hello("mock");
}
}
複製代碼
返回:bash
CustomInterceptor before
execute hello
CustomInterceptor after
複製代碼
Spring環境啓動過程當中,會調用AbstractApplicationContext.refresh()
,AOP的實現流程,也就是從這裏開始。app
obtainFreshBeanFactory()
執行過程當中,加載aop.xml,並根據namespace找到aop
對應的NamespaceHandler:AopNamespaceHandler
;AopNamespaceHandler
中,找到config標籤對應的BeanDefinitionParser的實現對象,也就是ConfigBeanDefinitionParser
;ConfigBeanDefinitionParser.parse
,有兩個做用:
AspectJAwareAdvisorAutoProxyCreator
註冊BeanDefinition;pointcut
,advisor
等標籤,並將相關對象註冊爲BeanDefinition。AspectJAwareAdvisorAutoProxyCreator
是BeanPostProcessor的實現類AbstractAutoProxyCreator
的子類。註冊BeanPostProcessor後,AspectJAwareAdvisorAutoProxyCreator
會在Spring建立bean的代理過程當中調用。Spring環境的加載,須要調用AbstractApplicationContext.refresh()。ide
在refresh()方法中,執行ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
建立BeanFacotry的時候,加載並解析xml資源。post
在這個過程當中,會調用BeanDefinitionParserDelegate.parseCustomElement
進行擴展標籤的解析:ui
public BeanDefinition parseCustomElement(Element ele, BeanDefinition containingBd) {
// 獲取namespace
String namespaceUri = getNamespaceURI(ele);
// 根據文件META-INF/spring.handlers,獲取對應的NamespaceHandler
NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);
if (handler == null) {
error("Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri + "]", ele);
return null;
}
// 調用NamespaceHandler.parse方法,返回BeanDefinition
return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));
}
複製代碼
詳細過程可參考Spring自定義標籤配置的源碼解析與實現。
對於<aop:config/>
,Spring會根據xmlns
去META-INF/spring.handlers
文件中查找相應的namespace解析類: http\://www.springframework.org/schema/aop=org.springframework.aop.config.AopNamespaceHandler
。
在AopNamespaceHandler
中: registerBeanDefinitionParser("config", new ConfigBeanDefinitionParser());
因此:
aop
namespace的解析類是AopNamespaceHandler
<aop:config/>
標籤的解析類是ConfigBeanDefinitionParser
,在 ConfigBeanDefinitionParser
中,<aop:config/>
定義的各個元素被解析爲 BeanDefinition
。ConfigBeanDefinitionParser
實現了BeanDefinitionParser
接口,在parse(Element element, ParserContext parserContext)
方法中,實現了兩部分功能:
AspectJAwareAdvisorAutoProxyCreator
;@Override
@Nullable
public BeanDefinition parse(Element element, ParserContext parserContext) {
CompositeComponentDefinition compositeDef =
new CompositeComponentDefinition(element.getTagName(), parserContext.extractSource(element));
parserContext.pushContainingComponent(compositeDef);
// 註冊AspectJAwareAdvisorAutoProxyCreator爲BeanDefinition
configureAutoProxyCreator(parserContext, element);
List<Element> childElts = DomUtils.getChildElements(element);
for (Element elt: childElts) {
String localName = parserContext.getDelegate().getLocalName(elt);
if (POINTCUT.equals(localName)) {
// 解析pointcut
parsePointcut(elt, parserContext);
}
else if (ADVISOR.equals(localName)) {
// 解析advisor
parseAdvisor(elt, parserContext);
}
else if (ASPECT.equals(localName)) {
parseAspect(elt, parserContext);
}
}
parserContext.popAndRegisterContainingComponent();
return null;
}
複製代碼
其中:
private static final String POINTCUT = "pointcut";
private static final String ADVISOR = "advisor";
private static final String ASPECT = "aspect";
複製代碼
AspectJAwareAdvisorAutoProxyCreator
是AbstractAutoProxyCreator
的子類;BeanPostProcessor
;postProcessAfterInitialization
的實現中,調用wrapIfNecessary
進行bean代理。@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (!this.earlyProxyReferences.contains(cacheKey)) {
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
複製代碼
Spring在實例化bean的過程當中,會調用BeanPostProcessor
對bean生成先後進行處理,aop利用這一點:
調用AbstractAutoProxyCreator.postProcessAfterInitialization
方法,根據pointcut
查找到相應的advisor
,對bean進行代理。
代碼執行流程:
1 ConfigBeanDefinitionParser.configureAutoProxyCreator;
2 AopNamespaceUtils.registerAspectJAutoProxyCreatorIfNecessary(parserContext, element);
public static void registerAspectJAutoProxyCreatorIfNecessary( ParserContext parserContext, Element sourceElement) {
// 註冊BeanDefinition
BeanDefinition beanDefinition = AopConfigUtils.registerAspectJAutoProxyCreatorIfNecessary(
parserContext.getRegistry(), parserContext.extractSource(sourceElement));
// 設置class-proxy
useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);
registerComponentIfNecessary(beanDefinition, parserContext);
}
複製代碼
3 AopConfigUtils.registerAspectJAutoProxyCreatorIfNecessary;
4 AopConfigUtils.registerOrEscalateApcAsRequired:
public static final String AUTO_PROXY_CREATOR_BEAN_NAME =
"org.springframework.aop.config.internalAutoProxyCreator";
RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
//// 省略代碼
registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
複製代碼
最終生成了
AspectJAwareAdvisorAutoProxyCreator
的BeanDefinition,beanName爲org.springframework.aop.config.internalAutoProxyCreator
。同時,
useClassProxyingIfNecessary
方法中,根據**aop:config/**中的proxy-target-class
,設置了AspectJAwareAdvisorAutoProxyCreator的一個父類ProxyConfig
的proxyTargetClass
屬性。
解析<aop:pointcut id="interceptorPointCuts" expression="execution(* com.xxx.yyy..*.*(..))"/>
,註冊AbstractExpressionPointcut
的BeanDefinition。
parsePointcut
private AbstractBeanDefinition parsePointcut(Element pointcutElement, ParserContext parserContext) {
String id = pointcutElement.getAttribute(ID);
// 獲取表達式 配置中的 expression="execution(* com.xxx.yyy..*.*(..))"
String expression = pointcutElement.getAttribute(EXPRESSION);
AbstractBeanDefinition pointcutDefinition = null;
try {
this.parseState.push(new PointcutEntry(id));
// 使用AspectJExpressionPointcut,爲pointcut建立BeanDefinition,
pointcutDefinition = createPointcutDefinition(expression);
pointcutDefinition.setSource(parserContext.extractSource(pointcutElement));
String pointcutBeanName = id;
if (StringUtils.hasText(pointcutBeanName)) {
// 以id爲beanName註冊AspectJExpressionPointcut爲bean.
parserContext.getRegistry().registerBeanDefinition(pointcutBeanName, pointcutDefinition);
}
else {
// 自動生成beanName註冊AspectJExpressionPointcut爲bean.
pointcutBeanName = parserContext.getReaderContext().registerWithGeneratedName(pointcutDefinition);
}
parserContext.registerComponent(
new PointcutComponentDefinition(pointcutBeanName, pointcutDefinition, expression));
}
finally {
this.parseState.pop();
}
return pointcutDefinition;
}
複製代碼
createPointcutDefinition
aop:pointcut
解析爲 AspectJExpressionPointcut
對象。AspectJExpressionPointcut extends AbstractExpressionPointcut
expression
是AbstractExpressionPointcut
的屬性protected AbstractBeanDefinition createPointcutDefinition(String expression) {
RootBeanDefinition beanDefinition = new RootBeanDefinition(AspectJExpressionPointcut.class);
beanDefinition.setScope(BeanDefinition.SCOPE_PROTOTYPE);
beanDefinition.setSynthetic(true);
beanDefinition.getPropertyValues().add(EXPRESSION, expression);
return beanDefinition;
}
複製代碼
解析<aop:advisor advice-ref="customInterceptor" pointcut-ref="interceptorPointCuts"/>
,註冊DefaultBeanFactoryPointcutAdvisor
的BeanDefinition。
parseAdvisor
createAdvisorBeanDefinition
建立advisor;parsePointcutProperty
獲取pointcut。private void parseAdvisor(Element advisorElement, ParserContext parserContext) {
// 1 建立bean : DefaultBeanFactoryPointcutAdvisor
AbstractBeanDefinition advisorDef = createAdvisorBeanDefinition(advisorElement, parserContext);
String id = advisorElement.getAttribute(ID);
try {
this.parseState.push(new AdvisorEntry(id));
String advisorBeanName = id;
// 2 註冊bean : DefaultBeanFactoryPointcutAdvisor
if (StringUtils.hasText(advisorBeanName)) {
parserContext.getRegistry().registerBeanDefinition(advisorBeanName, advisorDef);
}
else {
advisorBeanName = parserContext.getReaderContext().registerWithGeneratedName(advisorDef);
}
// 3 解析 pointcut-ref="interceptorPointCuts"
Object pointcut = parsePointcutProperty(advisorElement, parserContext);
if (pointcut instanceof BeanDefinition) {
// 返回的是有`pointcut`構造的BeanDefinition(AspectJExpressionPointcut對象),則設置`DefaultBeanFactoryPointcutAdvisor.pointcut = pointcut`
advisorDef.getPropertyValues().add(POINTCUT, pointcut);
parserContext.registerComponent(
new AdvisorComponentDefinition(advisorBeanName, advisorDef, (BeanDefinition) pointcut));
}
else if (pointcut instanceof String) {
// 返回的是beanName,則設置`DefaultBeanFactoryPointcutAdvisor.pointcut`爲一個運行時Bean引用。
advisorDef.getPropertyValues().add(POINTCUT, new RuntimeBeanReference((String) pointcut));
parserContext.registerComponent(
new AdvisorComponentDefinition(advisorBeanName, advisorDef));
}
}
finally {
this.parseState.pop();
}
}
複製代碼
createAdvisorBeanDefinition
DefaultBeanFactoryPointcutAdvisor
的BeanDefinition,DefaultBeanFactoryPointcutAdvisor是PointcutAdvisor
的一個實現;advice-ref
獲取advisor的Bean的beanName,即aop.xml中的customInterceptor。DefaultBeanFactoryPointcutAdvisor extends AbstractBeanFactoryPointcutAdvisor
,使用advice-ref
設置adviceBeanName
屬性,即前面的customInterceptor
。private static final String ADVICE_BEAN_NAME = "adviceBeanName";
private AbstractBeanDefinition createAdvisorBeanDefinition(Element advisorElement, ParserContext parserContext) {
// 建立`DefaultBeanFactoryPointcutAdvisor`的BeanDefinition;
RootBeanDefinition advisorDefinition = new RootBeanDefinition(DefaultBeanFactoryPointcutAdvisor.class);
advisorDefinition.setSource(parserContext.extractSource(advisorElement));
// 解析`advice-ref`獲取advice的Bean的beanName;
String adviceRef = advisorElement.getAttribute(ADVICE_REF);
if (!StringUtils.hasText(adviceRef)) {
parserContext.getReaderContext().error(
"'advice-ref' attribute contains empty value.", advisorElement, this.parseState.snapshot());
}
else {
// 設置AbstractBeanFactoryPointcutAdvisor的adviceBeanName屬性
advisorDefinition.getPropertyValues().add(
ADVICE_BEAN_NAME, new RuntimeBeanNameReference(adviceRef));
}
if (advisorElement.hasAttribute(ORDER_PROPERTY)) {
advisorDefinition.getPropertyValues().add(
ORDER_PROPERTY, advisorElement.getAttribute(ORDER_PROPERTY));
}
return advisorDefinition;
}
複製代碼
parsePointcutProperty
pointcut
,則使用expression調用createPointcutDefinition,構造AspectJExpressionPointcut的bean後直接返回。pointcut-ref
指定的bean做爲Pointcut。因此:pointcut優先於 pointcut-ref,有pointcut就再也不解析pointcut-ref。
private Object parsePointcutProperty(Element element, ParserContext parserContext) {
if (element.hasAttribute(POINTCUT) && element.hasAttribute(POINTCUT_REF)) {
parserContext.getReaderContext().error(
"Cannot define both 'pointcut' and 'pointcut-ref' on <advisor> tag.",
element, this.parseState.snapshot());
return null;
}
else if (element.hasAttribute(POINTCUT)) {
// 屬性有`pointcut`,則使用expression調用createPointcutDefinition,構造AspectJExpressionPointcut的bean後直接返回。
String expression = element.getAttribute(POINTCUT);
AbstractBeanDefinition pointcutDefinition = createPointcutDefinition(expression);
pointcutDefinition.setSource(parserContext.extractSource(element));
// 返回BeanDefinition
return pointcutDefinition;
}
else if (element.hasAttribute(POINTCUT_REF)) {
String pointcutRef = element.getAttribute(POINTCUT_REF);
if (!StringUtils.hasText(pointcutRef)) {
parserContext.getReaderContext().error(
"'pointcut-ref' attribute contains empty value.", element, this.parseState.snapshot());
return null;
}
// 返回pointcut-ref的beanName
return pointcutRef;
}
else {
parserContext.getReaderContext().error(
"Must define one of 'pointcut' or 'pointcut-ref' on <advisor> tag.",
element, this.parseState.snapshot());
return null;
}
}
複製代碼
AspectJAwareAdvisorAutoProxyCreator
,beanName是org.springframework.aop.config.internalAutoProxyCreator
;AbstractExpressionPointcut
,設置了expression屬性;DefaultBeanFactoryPointcutAdvisor
,pointcut屬性設置爲AbstractExpressionPointcut
。在AbstractApplicationContext.refresh()方法中,建立ConfigurableListableBeanFactory
後,會執行registerBeanPostProcessors
向Spring環境註冊BeanPostProcessor
。
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
複製代碼
AspectJAwareAdvisorAutoProxyCreator
在這個時候被加入到用於處理bean建立的BeanPostProcessor列表中。
簡要過程以下:
PostProcessorRegistrationDelegate.registerBeanPostProcessors
;beanFactory.getBean(ppName, BeanPostProcessor.class);
獲取BeanPostProcessor列表;beanFactory.addBeanPostProcessor(postProcessor)
。createProxy
Spring建立Bean,是在AbstractAutowireCapableBeanFactory.doCreateBean
方法中:
AbstractAutowireCapableBeanFactory.doCreateBean
中調用了initializeBean
:// Initialize the bean instance.
Object exposedObject = bean;
try {
populateBean(beanName, mbd, instanceWrapper);
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
複製代碼
initializeBean
中:if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
複製代碼
applyBeanPostProcessorsAfterInitialization
執行了BeanPostProcessor.postProcessAfterInitialization方法:@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException {
Object result = existingBean;
for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
Object current = beanProcessor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
複製代碼
AbstractAutoProxyCreator.postProcessAfterInitialization
就在這裏執行:@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (!this.earlyProxyReferences.contains(cacheKey)) {
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
複製代碼
wrapIfNecessary
中使用advisor執行createProxy:// Create proxy if we have advice.
// 1 查找advisor
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
// 2 建立proxy,並使用advisor進行加強
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
複製代碼
AbstractAutoProxyCreator.getAdvicesAndAdvisorsForBean
是一個抽象方法,由子類AbstractAdvisorAutoProxyCreator
實現。
AbstractAdvisorAutoProxyCreator.getAdvicesAndAdvisorsForBean
調用了findEligibleAdvisors
,主要實現兩個流程:
/* beanClass:要代理的類 beanName:當前要代理的bean的beanName */
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
// 1 獲取候選的advisors
List<Advisor> candidateAdvisors = findCandidateAdvisors();
// 2 過濾出匹配的advisors
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
複製代碼
findCandidateAdvisors
調用BeanFactoryAdvisorRetrievalHelper.findAdvisorBeans
,獲取到全部實現了Advisor接口的Bean,主要代碼片斷以下:
1 找到是有實現了Advisor接口的beanName:
advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors( this.beanFactory, Advisor.class, true, false);
2 根據beanName獲取Bean:
List<Advisor> advisors = new LinkedList<>();
....
advisors.add(this.beanFactory.getBean(name, Advisor.class));
....
return advisors;
複製代碼
findAdvisorsThatCanApply
過濾出匹配的Advisor,主要經過AopUtils.findAdvisorsThatCanApply,調用canApply
實現:
public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
if (candidateAdvisors.isEmpty()) {
return candidateAdvisors;
}
List<Advisor> eligibleAdvisors = new LinkedList<>();
for (Advisor candidate : candidateAdvisors) {
// 調用 canApply
if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
eligibleAdvisors.add(candidate);
}
}
boolean hasIntroductions = !eligibleAdvisors.isEmpty();
for (Advisor candidate : candidateAdvisors) {
if (candidate instanceof IntroductionAdvisor) {
// already processed
continue;
}
// 調用canApply
if (canApply(candidate, clazz, hasIntroductions)) {
eligibleAdvisors.add(candidate);
}
}
return eligibleAdvisors;
}
複製代碼
canApply
IntroductionAdvisor
,則調用IntroductionAdvisor.ClassFilter.matchs進行判斷;PointcutAdvisor
(好比前面建立的DefaultBeanFactoryPointcutAdvisor),則先調用PointcutAdvisor.ClassFilter.matches進行判斷,再MethodMatcher.getMethodMatcher()進行判斷。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 {
// It doesn't have a pointcut so we assume it applies.
return true;
}
}
public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
Assert.notNull(pc, "Pointcut must not be null");
if (!pc.getClassFilter().matches(targetClass)) {
return false;
}
MethodMatcher methodMatcher = pc.getMethodMatcher();
if (methodMatcher == MethodMatcher.TRUE) {
// No need to iterate the methods if we're matching any method anyway...
return true;
}
IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
}
Set<Class<?>> classes = new LinkedHashSet<>(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
classes.add(targetClass);
for (Class<?> clazz : classes) {
Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
for (Method method : methods) {
if ((introductionAwareMethodMatcher != null &&
introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions)) ||
methodMatcher.matches(method, targetClass)) {
return true;
}
}
}
return false;
}
複製代碼
在AbstractAutoProxyCreator.createProxy
中實現:
protected Object createProxy(Class<?> beanClass, @Nullable String beanName, @Nullable Object[] specificInterceptors, TargetSource targetSource) {
if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
}
// 建立ProxyFactory
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
// 判斷proxyTargetClass
if (!proxyFactory.isProxyTargetClass()) {
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
else {
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
// buildAdvisors
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
proxyFactory.addAdvisors(advisors);
proxyFactory.setTargetSource(targetSource);
customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
// 執行getProxy
return proxyFactory.getProxy(getProxyClassLoader());
}
複製代碼
proxyFactory.getProxy
中,須要一個AopProxy
去實現,AopProxy
的建立,在DefaultAopProxyFactory
中,返回一個JdkDynamicAopProxy
或一個CglibAopProxy
。
@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);
}
return new ObjenesisCglibAopProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}
複製代碼
JdkDynamicAopProxy實現了java.lang.reflect.InvocationHandler
接口,在invoke(Object proxy, Method method, Object[] args)
中實現代理。代碼片斷以下:
// Get the interception chain for this method.
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
// Check whether we have any advice. If we don't, we can fallback on direct
// reflective invocation of the target, and avoid creating a MethodInvocation.
if (chain.isEmpty()) {
// We can skip creating a MethodInvocation: just invoke the target directly
// Note that the final invoker must be an InvokerInterceptor so we know it does
// nothing but a reflective operation on the target, and no hot swapping or fancy proxying.
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
}
else {
// We need to create a method invocation...
invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
// Proceed to the joinpoint through the interceptor chain.
retVal = invocation.proceed();
}
複製代碼
調用
ReflectiveMethodInvocation.proceed()
實現了代理。
ObjenesisCglibAopProxy是CglibAopProxy
的子類,代理邏輯都實如今CglibAopProxy
裏。
CglibAopProxy中獲取Callback數組時,建立了DynamicAdvisedInterceptor對象。
private Callback[] getCallbacks(Class<?> rootClass){
//省略代碼
// Choose an "aop" interceptor (used for AOP calls).
Callback aopInterceptor = new DynamicAdvisedInterceptor(this.advised);
//省略代碼
}
複製代碼
DynamicAdvisedInterceptor
實現了org.springframework.cglib.proxy.MethodInterceptor
接口,在intercept
方法裏執行了代理:
// We need to create a method invocation...
retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
複製代碼
CglibMethodInvocation是
ReflectiveMethodInvocation
的子類,因此也是調用ReflectiveMethodInvocation.proceed()
實現了代理。