3.0手写spring-AOP
3.0手写spring-AOP
AOP分析
切面增强点切入点等功能
通知切点织入分析
Advice设计
前置增强
后置增强
环绕增强
Advice接口设计
PontCut设计
AspectJ表达式
aop:pointcut 的expression 的各种表达式
任意公共方法的执行:
execution(public * *(…))
任何一个以“set”开始的方法的执行:
execution(* set*(…))
AccountService 接口的任意方法的执行:
execution(* com.xyz.service.AccountService.*(…))
定义在service包里的任意方法的执行:
execution(* com.xyz.service.*.*(…))
定义在service包或者子包里的任意方法的执行:
execution(* com.xyz.service…*.*(…))
在service包里的任意连接点(在Spring AOP中只是方法执行) :
within(com.xyz.service.*)
在service包或者子包里的任意连接点(在Spring AOP中只是方法执行) :
within(com.xyz.service…*)
实现了 AccountService 接口的代理对象的任意连接点(在Spring AOP中只是方法执行) :
this(com.xyz.service.AccountService)
'this’在binding form中用的更多:- 请常见以下讨论通知的章节中关于如何使得代理对象可以在通知体内访问到的部分。
实现了 AccountService 接口的目标对象的任意连接点(在Spring AOP中只是方法执行) :
target(com.xyz.service.AccountService)
'target’在binding form中用的更多:- 请常见以下讨论通知的章节中关于如何使得目标对象可以在通知体内访问到的部分。
任何一个只接受一个参数,且在运行时传入的参数实现了 Serializable 接口的连接点 (在Spring AOP中只是方法执行)
args(java.io.Serializable)
'args’在binding form中用的更多:- 请常见以下讨论通知的章节中关于如何使得方法参数可以在通知体内访问到的部分。 请注意在例子中给出的切入点不同于 execution(* *(java.io.Serializable)): args只有在动态运行时候传入参数是可序列化的(Serializable)才匹配,而execution 在传入参数的签名声明的类型实现了 Serializable 接口时候匹配。
有一个 @Transactional 注解的目标对象中的任意连接点(在Spring AOP中只是方法执行)
@target(org.springframework.transaction.annotation.Transactional)
‘@target’ 也可以在binding form中使用:请常见以下讨论通知的章节中关于如何使得annotation对象可以在通知体内访问到的部分。
任何一个目标对象声明的类型有一个 @Transactional 注解的连接点(在Spring AOP中只是方法执行)
@within(org.springframework.transaction.annotation.Transactional)
'@within’也可以在binding form中使用:- 请常见以下讨论通知的章节中关于如何使得annotation对象可以在通知体内访问到的部分。
任何一个执行的方法有一个 @Transactional annotation的连接点(在Spring AOP中只是方法执行)
@annotation(org.springframework.transaction.annotation.Transactional)
‘@annotation’ 也可以在binding form中使用:- 请常见以下讨论通知的章节中关于如何使得annotation对象可以在通知体内访问到的部分。
任何一个接受一个参数,并且传入的参数在运行时的类型实现了 @Classified annotation的连接点(在Spring AOP中只是方法执行)
@args(com.xyz.security.Classified)
PointCut标准接口设计
public interface Pointcut {
boolean matchsClass(Class<?> targetClass);
boolean matchsMethod(Method method, Class<?> targetClass);
}
AspectJPointCut表达式
仅使用了Aspect J的切点表达式而已
以及表达式的解析
AspectJ的表达式实现
public class AspectJExpressionPointcut implements Pointcut {
private static PointcutParser pp = PointcutParser
.getPointcutParserSupportingAllPrimitivesAndUsingContextClassloaderForResolution();
private String expression;
private PointcutExpression pe;
public AspectJExpressionPointcut(String expression) {
super();
this.expression = expression;
pe = pp.parsePointcutExpression(expression);
}
@Override
public boolean matchsClass(Class<?> targetClass) {
return pe.couldMatchJoinPointsInType(targetClass);
}
@Override
public boolean matchsMethod(Method method, Class<?> targetClass) {
ShadowMatch sm = pe.matchesMethodExecution(method);
return sm.alwaysMatches();
}
Advisor: Advice PointCut的 使用
Advisor通知者用于Advice和Pointcut的组合
public interface Advisor {
String getAdviceBeanName();
String getExpression();
}
public interface PointcutAdvisor extends Advisor {
Pointcut getPointcut();
}
public class AspectJPointcutAdvisor implements PointcutAdvisor {
private String adviceBeanName;
private String expression;
private AspectJExpressionPointcut pointcut;
public AspectJPointcutAdvisor(String adviceBeanName, String expression) {
super();
this.adviceBeanName = adviceBeanName;
this.expression = expression;
this.pointcut = new AspectJExpressionPointcut(this.expression);
}
@Override
public Pointcut getPointcut() {
return this.pointcut;
}
@Override
public String getAdviceBeanName() {
return this.adviceBeanName;
}
@Override
public String getExpression() {
return this.expression;
}
}
Adviosr的扩展
Weaving织入的分析
处于BeanFactory的过程。
观察者模式
BeanPostProcessor观察者模式的
public interface AdvisorRegistry {
public void registAdvisor(Advisor ad);
public List<Advisor> getAdvisors();
}
public interface BeanPostProcessor {
default Object postProcessBeforeInitialization(Object bean, String beanName) throws Throwable {
return bean;
}
default Object postProcessAfterInitialization(Object bean, String beanName) throws Throwable {
return bean;
}
}
public class AdvisorAutoProxyCreator implements AdvisorRegistry, BeanPostProcessor, BeanFactoryAware {
...
private List<Advisor> advisors;
public void registAdvisor(Advisor ad) {
this.advisors.add(ad);
}
public Object postProcessAfterInitialization(Object bean, String beanName) throws Throwable {
// 在此判断bean是否需要进行切面增强
List<Advisor> matchAdvisors = getMatchedAdvisors(bean, beanName);
// 如需要就进行增强,再返回增强的对象。
if (CollectionUtils.isNotEmpty(matchAdvisors)) {
bean = this.createProxy(bean, beanName, matchAdvisors);
}
return bean;
}
...
}
public interface BeanFactory {
/**
* 获取bean
* @param name
bean的名字
* @return bean 实例
*/
Object getBean(String name) throws Throwable;
void registerBeanPostProcessor(BeanPostProcessor bpp);
}
public class DefaultBeanFactory implements BeanFactory, BeanDefinitionRegistry, Closeable {
private List<BeanPostProcessor> beanPostProcessors = Collections.synchronizedList(new ArrayList<>());
@Override
public void registerBeanPostProcessor(BeanPostProcessor bpp) {
this.beanPostProcessors.add(bpp);
if (bpp instanceof BeanFactoryAware) {
((BeanFactoryAware) bpp).setBeanFactory(this);
}
}
protected Object doGetBean(String beanName) throws Throwable {
...
// 应用bean初始化前的处理
instance = this.applyPostProcessBeforeInitialization(instance, beanName);
// 执行初始化方法
this.doInit(bd, instance);
// 应用bean初始化后的处理
instance = this.applyPostProcessAfterInitialization(instance, beanName);
...
}
...
}
Weaving织入的实现
Class获取的信息
获取该类及其父类中所有公共(public)方法的数组。
@CallerSensitive
public Method[] getMethods() throws SecurityException {
checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
return copyMethods(privateGetPublicMethods());
}
获取该类中指定名称和参数类型的声明方法(包括私有方法)。
@CallerSensitive
public Method getDeclaredMethod(String name, Class<?>... parameterTypes)
throws NoSuchMethodException, SecurityException {
checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
Method method = searchMethods(privateGetDeclaredMethods(false), name, parameterTypes);
if (method == null) {
throw new NoSuchMethodException(getName() + "." + name + argumentTypesToString(parameterTypes));
}
return method;
}
判断代理增强
public Object postProcessAfterInitialization(Object bean, String beanName) throws Throwable {
// 在此判断bean是否需要进行切面增强
List<Advisor> matchAdvisors = getMatchedAdvisors(bean, beanName);
// 如需要就进行增强,再返回增强的对象。
if (CollectionUtils.isNotEmpty(matchAdvisors)) {
bean = this.createProxy(bean, beanName, matchAdvisors);
}
return bean;
}
获取所有的方法
private List<Advisor> getMatchedAdvisors(Object bean, String beanName) {
if (CollectionUtils.isEmpty(advisors)) {
return null;
}
// 得到类、所有的方法
Class<?> beanClass = bean.getClass();
List<Method> allMethods = this.getAllMethodForClass(beanClass);
// 存放匹配的Advisor的list
List<Advisor> matchAdvisors = new ArrayList<>();
// 遍历Advisor来找匹配的
for (Advisor ad : this.advisors) {
if (ad instanceof PointcutAdvisor) {
if (isPointcutMatchBean((PointcutAdvisor) ad, beanClass, allMethods)) {
matchAdvisors.add(ad);
}
}
}
return matchAdvisors;
}
private List<Method> getAllMethodForClass(Class<?> beanClass) {
List<Method> allMethods = new LinkedList<>();
Set<Class<?>> classes = new LinkedHashSet<>(ClassUtils.getAllInterfacesForClassAsSet(beanClass));
classes.add(beanClass);
for (Class<?> clazz : classes) {
Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
for (Method m : methods) {
allMethods.add(m);
}
}
return allMethods;
}
Pointcut进行匹配过程
private boolean isPointcutMatchBean(PointcutAdvisor pa, Class<?> beanClass, List<Method> methods) {
Pointcut p = pa.getPointcut();
// 首先判断类是否匹配
if (!p.matchsClass(beanClass)) {
return false;
}
// 再判断是否有方法匹配
for (Method method : methods) {
if (p.matchsMethod(method, beanClass)) {
return true;
}
}
return false;
}
代理增强的逻辑
创建代理
private Object createProxy(Object bean, String beanName, List<Advisor> matchAdvisors) throws Throwable {
// 通过AopProxyFactory工厂去完成选择、和创建代理对象的工作。
return AopProxyFactory.getDefaultAopProxyFactory().createAopProxy(bean, beanName, matchAdvisors, beanFactory)
.getProxy();
}
public interface AopProxy {
/**
* Create a new proxy object.
* <p>
* Uses the AopProxy's default class loader (if necessary for proxy
* creation): usually, the thread context class loader.
*
* @return the new proxy object (never {@code null})
* @see Thread#getContextClassLoader()
*/
Object getProxy();
/**
* Create a new proxy object.
* <p>
* Uses the given class loader (if necessary for proxy creation).
* {@code null} will simply be passed down and thus lead to the low-level
* proxy facility's default, which is usually different from the default
* chosen by the AopProxy implementation's {@link #getProxy()} method.
*
* @param classLoader
* the class loader to create the proxy with (or {@code null} for
* the low-level proxy facility's default)
* @return the new proxy object (never {@code null})
*/
Object getProxy(ClassLoader classLoader);
}
public interface AopProxyFactory {
AopProxy createAopProxy(Object bean, String beanName, List<Advisor> matchAdvisors, BeanFactory beanFactory)
throws Throwable;
/**
* 获得默认的AopProxyFactory实例
*
* @return AopProxyFactory
*/
static AopProxyFactory getDefaultAopProxyFactory() {
return new DefaultAopProxyFactory();
}
}
Creator怎么使用AopProxy
public class DefaultAopProxyFactory implements AopProxyFactory {
@Override
public AopProxy createAopProxy(Object bean, String beanName, List<Advisor> matchAdvisors, BeanFactory beanFactory)
throws Throwable {
// 是该用jdk动态代理还是cglib?
if (shouldUseJDKDynamicProxy(bean, beanName)) {
return new JdkDynamicAopProxy(beanName, bean, matchAdvisors, beanFactory);
} else {
return new CglibDynamicAopProxy(beanName, bean, matchAdvisors, beanFactory);
}
}
private boolean shouldUseJDKDynamicProxy(Object bean, String beanName) {
// 如何判断?
// 这样可以吗:有实现接口就用JDK,没有就用cglib?
// 请同学们在读spring的源码时看spring中如何来判断的
return false;
}
}
//CGlib代理
@Override
public Object getProxy(ClassLoader classLoader) {
if (logger.isDebugEnabled()) {
logger.debug("为" + target + "创建cglib代理。");
}
Class<?> superClass = this.target.getClass();
enhancer.setSuperclass(superClass);
enhancer.setInterfaces(this.getClass().getInterfaces());
enhancer.setCallback(this);
Constructor<?> constructor = null;
try {
constructor = superClass.getConstructor(new Class<?>[] {});
} catch (NoSuchMethodException | SecurityException e) {
}
if (constructor != null) {
return enhancer.create();
} else {
BeanDefinition bd = ((DefaultBeanFactory) beanFactory).getBeanDefinition(beanName);
/*
其中这里的bd.getConstructorArgumentRealValues()
private ThreadLocal<Object[]> realConstructorArgumentValues = new ThreadLocal<>();
@Override
public Object[] getConstructorArgumentRealValues() {
return realConstructorArgumentValues.get();
}
*/
return enhancer.create(bd.getConstructor().getParameterTypes(), bd.getConstructorArgumentRealValues());
}
}
//JDK代理
@Override
public Object getProxy(ClassLoader classLoader) {
if (logger.isDebugEnabled()) {
logger.debug("为" + target + "创建代理。");
}
return Proxy.newProxyInstance(classLoader, target.getClass().getInterfaces(), this);
}
实现增强的逻辑
Cglib的使用
@Override
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
return AopProxyUtils.applyAdvices(target, method, args, matchAdvisors, proxy, beanFactory);
}
JDK的代理使用
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return AopProxyUtils.applyAdvices(target, method, args, matchAdvisors, proxy, beanFactory);
}
/**
* 对方法应用advices增强
*/
public static Object applyAdvices(Object target, Method method, Object[] args, List<Advisor> matchAdvisors,
Object proxy, BeanFactory beanFactory) throws Throwable {
// 这里要做什么?
// 1、获取要对当前方法进行增强的advice
List<Object> advices = AopProxyUtils.getShouldApplyAdvices(target.getClass(), method, matchAdvisors,
beanFactory);
// 2、如有增强的advice,责任链式增强执行
if (CollectionUtils.isEmpty(advices)) {
return method.invoke(target, args);
} else {
// 责任链式执行增强
AopAdviceChainInvocation chain = new AopAdviceChainInvocation(proxy, target, method, args, advices);
return chain.invoke();
}
}
/**
* 获取与方法匹配的切面的advices
*/
public static List<Object> getShouldApplyAdvices(Class<?> beanClass, Method method, List<Advisor> matchAdvisors,
BeanFactory beanFactory) throws Throwable {
if (CollectionUtils.isEmpty(matchAdvisors)) {
return null;
}
List<Object> advices = new ArrayList<>();
for (Advisor ad : matchAdvisors) {
if (ad instanceof PointcutAdvisor) {
if (((PointcutAdvisor) ad).getPointcut().matchsMethod(method, beanClass)) {
advices.add(beanFactory.getBean(ad.getAdviceBeanName()));
}
}
}
return advices;
}
// 责任链执行记录索引号
private int i = 0;
public Object invoke() throws Throwable {
if (i < this.advices.size()) {
Object advice = this.advices.get(i++);
if (advice instanceof MethodBeforeAdvice) {
// 执行前置增强
((MethodBeforeAdvice) advice).before(method, args, target);
} else if (advice instanceof MethodInterceptor) {
// 执行环绕增强和异常处理增强。注意这里给入的method 和 对象 是invoke方法和链对象
return ((MethodInterceptor) advice).invoke(invokeMethod, null, this);
} else if (advice instanceof AfterReturningAdvice) {
// 当是后置增强时,先得得到结果,再执行后置增强逻辑
Object returnValue = this.invoke();
((AfterReturningAdvice) advice).afterReturning(returnValue, method, args, target);
return returnValue;
}
return this.invoke();
} else {
return method.invoke(target, args);
}
}