转载自:https://blog.youkuaiyun.com/luanlouis/article/details/51155821
1、Spring内部创建代理对象的过程
在Spring的底层,如果配置了AOP,Spring会为每一个Bean创建一个对应的ProxyFactoryBean的FactoryBean来创建某个对象的代理对象。
假定有一个接口TicketService及其实现类RailwayStation,打算创建一个代理类,在执行TicketService的方法时的各个阶段,插入对应的业务代码。
public interface TicketService {
//售票
public void sellTicket();
//问询
public void inquire();
//退票
public void withdraw();
}
public class RailwayStation implements TicketService {
public void sellTicket(){
System.out.println("售票............");
}
public void inquire() {
System.out.println("问询.............");
}
public void withdraw() {
System.out.println("退票.............");
}
}
public class TicketServiceBeforeAdvice implements MethodBeforeAdvice {
public void before(Method method, Object[] args, Object target) throws Throwable {
System.out.println("BEFORE_ADVICE: 欢迎光临代售点....");
}
}
public class TicketServiceAfterReturningAdvice implements AfterReturningAdvice {
@Override
public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
System.out.println("AFTER_RETURNING:本次服务已结束....");
}
}
public class TicketServiceAroundAdvice implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.println("AROUND_ADVICE:BEGIN....");
Object returnValue = invocation.proceed();
System.out.println("AROUND_ADVICE:END.....");
return returnValue;
}
}
public class TicketServiceThrowsAdvice implements ThrowsAdvice {
public void afterThrowing(Exception ex) {
System.out.println("AFTER_THROWING....");
}
public void afterThrowing(Method method, Object[] args, Object target, Exception ex) {
System.out.println("调用过程出错啦!!!!!");
}
}
然后来手动使用ProxyFactoryBean来创建Proxy对象,并将相应的几种不同的Advice加入这个proxy对应的各个执行阶段中:
public static void main(String[] args) {
Advice beforeAdvice = new TicketServiceBeforeAdvice();
Advice afterReturningAdvice = new TicketServiceAfterReturningAdvice();
Advice aroundAdvice = new TicketServiceAroundAdvice();
Advice throwsAdvice = new TicketServiceThrowsAdvice();
RailwayStation railwayStation = new RailwayStation();
// 创建ProxyFactoryBean,用以创建指定对象的Proxy对象
ProxyFactoryBean proxyFactoryBean = new ProxyFactoryBean();
// 设置Proxy的接口
proxyFactoryBean.setInterfaces(TicketService.class);
// 设置RealSubject
proxyFactoryBean.setTarget(railwayStation);
// 使用JDK基于接口实现机制的动态代理生成Proxy代理对象,如果想使用CGLIB,需要将这个flag设置成true
proxyFactoryBean.setProxyTargetClass(false);
// 添加不同的Advice
proxyFactoryBean.addAdvice(afterReturningAdvice);
proxyFactoryBean.addAdvice(aroundAdvice);
proxyFactoryBean.addAdvice(throwsAdvice);
proxyFactoryBean.addAdvice(beforeAdvice);
// 通过ProxyFactoryBean生成Proxy对象
TicketService ticketService = (TicketService) proxyFactoryBean.getObject();
ticketService.sellTicket();
}
运行结果:
AROUND_ADVICE:BEGIN....
BEFORE_ADVICE: 欢迎光临代售点....
售票............
AROUND_ADVICE:END.....
AFTER_RETURNING:本次服务已结束....
我们成功地创建了一个通过一个ProxyFactoryBean和真实的实例对象创建出了对应的代理对象,并将各个Advice加入到proxy代理对象中。
2、Spring AOP的核心ProxyFactoryBean
上面通过了使用ProxyFactoryBean实现了AOP的功能,在使用时通过addAdvice(Advice advice)把各类Advice添加到ProxyFactoryBean(实际是父类AdvisedSupport)中:
public void addAdvice(Advice advice) throws AopConfigException {
int pos = this.advisors.size();
addAdvice(pos, advice);
}
AdvisedSupport中维护了private List<Advisor> advisors = new LinkedList<Advisor>();列表,addAdvice中会把advice包装为DefaultPointcutAdvisor加入到这个列表里。
也就是说ProxyFactoryBean知道Advice信息,可以根据特定的类名和方法名返回对应的AdviceChain,用以表示需要执行的Advice串。当使用proxy时,对proxy对象调用的方法,都最终被转到这个类的invoke()方法中。以JdkDynamicAopProxy为例:
final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {
//...略
/** Proxy的配置信息,这里主要提供Advisor列表,并用于返回AdviceChain */
private final AdvisedSupport advised;
//...略
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
MethodInvocation invocation;
Object oldProxy = null;
boolean setProxyContext = false;
TargetSource targetSource = this.advised.targetSource;
Class<?> targetClass = null;
Object target = null;
try {
//...略
Object retVal;
//...略
// 获取当前调用方法的拦截链
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
// 如果没有拦截链,则直接调用Joinpoint连接点的方法。
if (chain.isEmpty()) {
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
}
else {
// 根据给定的拦截链和方法调用信息,创建新的MethodInvocation对象,
// 整个拦截链的工作逻辑都在这个ReflectiveMethodInvocation里
invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
retVal = invocation.proceed();
}
//...略
return retVal;
}
finally {
//...略
}
}
}
来看关键的getInterceptorsAndDynamicInterceptionAdvice函数:
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, Class<?> targetClass) {
MethodCacheKey cacheKey = new MethodCacheKey(method);
List<Object> cached = this.methodCache.get(cacheKey);
if (cached == null) {
cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(
this, method, targetClass);
this.methodCache.put(cacheKey, cached);
}
return cached;
}
最终是调用到了DefaultAdvisorChainFactory#getInterceptorsAndDynamicInterceptionAdvice:
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
Advised config, Method method, Class<?> targetClass) {
// This is somewhat tricky... We have to process introductions first,
// but we need to preserve order in the ultimate list.
List<Object> interceptorList = new ArrayList<Object>(config.getAdvisors().length);
Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
boolean hasIntroductions = hasMatchingIntroductions(config, actualClass);
AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
for (Advisor advisor : config.getAdvisors()) {
if (advisor instanceof PointcutAdvisor) {
// Add it conditionally.
PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
if (MethodMatchers.matches(mm, method, actualClass, hasIntroductions)) {
if (mm.isRuntime()) {
// Creating a new object instance in the getInterceptors() method
// isn't a problem as we normally cache created chains.
for (MethodInterceptor interceptor : interceptors) {
interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
}
}
else {
interceptorList.addAll(Arrays.asList(interceptors));
}
}
}
}
else if (advisor instanceof IntroductionAdvisor) {
//...略
}
else {
//...略
}
}
return interceptorList;
}
代码比较长,主要看for循环的第一个if分支。config.getAdvisors()返回的就是之前通过addAdvisor添加的Advisor列表(new DefaultPointcutAdvisor(advice))。registry.getInterceptors(advisor)是把advisor转换成MethodInterceptor[]:
public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
List<MethodInterceptor> interceptors = new ArrayList<MethodInterceptor>(3);
Advice advice = advisor.getAdvice();
if (advice instanceof MethodInterceptor) {
interceptors.add((MethodInterceptor) advice);
}
for (AdvisorAdapter adapter : this.adapters) {
if (adapter.supportsAdvice(advice)) {
interceptors.add(adapter.getInterceptor(advisor));
}
}
if (interceptors.isEmpty()) {
throw new UnknownAdviceTypeException(advisor.getAdvice());
}
return interceptors.toArray(new MethodInterceptor[interceptors.size()]);
}
AdvisorAdapter的实例有AfterReturningAdviceAdapter、MethodBeforeAdviceAdapter、ThrowsAdviceAdapter分别用于转换AfterReturningAdvice、MethodBeforeAdvice、ThrowsAdvice为AfterReturningAdviceInterceptor、MethodBeforeAdviceInterceptor、ThrowsAdviceInterceptor。注意,示例代码里的TicketServiceAroundAdvice类是MethodInterceptor的子类,不需要AdvisorAdapter转换。
这里创建MethodInterceptor链,然后构造ReflectiveMethodInvocation实例,调用proceed():
@Override
public Object proceed() throws Throwable {
// We start with an index of -1 and increment early.
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}
// 取得第拦截器链上第N个拦截器
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
// Evaluate dynamic method matcher here: static part will already have
// been evaluated and found to match.
InterceptorAndDynamicMethodMatcher dm =
(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {
return dm.interceptor.invoke(this);
}
else {
// Dynamic matching failed.
// Skip this interceptor and invoke the next in the chain.
return proceed();
}
}
else {
// It's an interceptor, so we just invoke it: The pointcut will have
// been evaluated statically before this object was constructed.
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
初始时,this.currentInterceptorIndex=-1,this.interceptorsAndDynamicMethodMatchers即先前创建的MethodInterceptor[]。
第一步,取MethodInterceptor[]中的第0个,即AfterReturningAdviceInterceptor:
public class AfterReturningAdviceInterceptor implements MethodInterceptor, AfterAdvice, Serializable {
private final AfterReturningAdvice advice;
public AfterReturningAdviceInterceptor(AfterReturningAdvice advice) {
Assert.notNull(advice, "Advice must not be null");
this.advice = advice;
}
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
Object retVal = mi.proceed();
this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());
return retVal;
}
}
先执行mi.proceed(),即ReflectiveMethodInvocation实例的proceed()方法,进入proceed()后,取MethodInterceptor[]中的第1个,即TicketServiceAroundAdvice:
public class TicketServiceAroundAdvice implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.println("AROUND_ADVICE:BEGIN....");
Object returnValue = invocation.proceed();
System.out.println("AROUND_ADVICE:END.....");
return returnValue;
}
}
同理再次进入proceed()后,取MethodInterceptor[]中的第2个,即ThrowsAdviceInterceptor:
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
try {
return mi.proceed();
}
catch (Throwable ex) {
Method handlerMethod = getExceptionHandler(ex);
if (handlerMethod != null) {
invokeHandlerMethod(mi, ex, handlerMethod);
}
throw ex;
}
}
之后进入proceed()后,取MethodInterceptor[]中的第3个,MethodBeforeAdviceInterceptor:
public class MethodBeforeAdviceInterceptor implements MethodInterceptor, Serializable {
private MethodBeforeAdvice advice;
public MethodBeforeAdviceInterceptor(MethodBeforeAdvice advice) {
Assert.notNull(advice, "Advice must not be null");
this.advice = advice;
}
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis() );
return mi.proceed();
}
}
之后进入proceed(),this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1满足条件,进入invokeJoinpoint:
protected Object invokeJoinpoint() throws Throwable {
return AopUtils.invokeJoinpointUsingReflection(this.target, this.method, this.arguments);
}
这里执行被代理对象的方法调用。然后根据方法栈的调用依次执行完MethodBeforeAdviceInterceptor->ThrowsAdviceInterceptor->TicketServiceAroundAdvice->AfterReturningAdviceInterceptor。所以最终的运行情况是:
AROUND_ADVICE:BEGIN....
BEFORE_ADVICE: 欢迎光临代售点....
售票............
AROUND_ADVICE:END.....
AFTER_RETURNING:本次服务已结束....
1653

被折叠的 条评论
为什么被折叠?



