ClassFilter 和 MethodMatcher ,其实可以很好的理解,如何定义一个切入点?我们在定义切入点的时候,就是想对某一个类的全部方法,或者对某一个类的部方法进行切入,因此在判断能否作用到方法上的时候,先判断是否类能够匹配(ClassFilter的活),之后再判断方法是否匹配(MethodMatcher的活)。 AspectJExpressionPointcut 【这个类主要是解析execution表达式的,这个类同时实现了ClassFilter和MethodMatcher,具备了两者的功能,因此可以直接使用该类进行切入点的匹配】、 AnnotationMatchingPointcut 【注解的PointCut,主要用来匹配注解,底层使用就是 AnnotationMethodMatcher 和 AnnotationMethodClassFilter ,后续会讲到】 源码如下:
public interface Pointcut{
//返回一个ClassFilter
ClassFiltergetClassFilter();
//返回一个MethodMatcher
MethodMatchergetMethodMatcher();
//TruePointCut,对应任何的方法都是匹配(总是匹配)
Pointcut TRUE = TruePointcut.INSTANCE;
}
AspectJExpressionPointcut 演示如下:
@Test
public void testAspectJExpressionPointCut()throws NoSuchMethodException {
AspectJExpressionPointcut expressionPointcut = new AspectJExpressionPointcut();
//设置aspectj表达式,这个比较常用的表达式
expressionPointcut.setExpression("execution(* cn.tedu.demo.service.UserService.addUser(..))");
//匹配类
boolean b = expressionPointcut.matches(UserService.class);
//直接调用matches匹配方法
boolean a = expressionPointcut.matches(UserService.class.getDeclaredMethod("addUser", User.class), UserService.class);
System.out.println(a+"--->"+b);
}
@Test
public void testAnnotationMatchingPointcut()throws NoSuchMethodException {
//第一个参数是注解,第二参数表示是否在接口和父类的查找该注解
AnnotationMatchingPointcut pointcut = new AnnotationMatchingPointcut(Transactional.class, false);
//匹配方法上是否有@Transactional注解
boolean a = pointcut.getMethodMatcher().matches(UserService.class.getDeclaredMethod("addUser", User.class), UserService.class);
//匹配类上是否有@Transactional注解
boolean b = pointcut.getClassFilter().matches(UserService.class);
System.out.println(a+"--->"+b);
}
@Test
public void testPointcuts()throws NoSuchMethodException {
AnnotationMatchingPointcut annotationMatchingPointcut = new AnnotationMatchingPointcut(Transactional.class, false);
Class cls=UserService.class;
Method method = cls.getDeclaredMethod("addUser", User.class);
//调用matches方法,判断UserService的addUser方法是否有@Transactional注解
boolean matches = Pointcuts.matches(annotationMatchingPointcut, method, cls);
System.out.println(matches);
}
@FunctionalInterface
public interface ClassFilter{
//判断方法
boolean matches(Class<?> clazz);
//定义一个总是匹配的TrueClassFilter,其实就是matches方法总是返回true
ClassFilter TRUE = TrueClassFilter.INSTANCE;
}
ClassFilter在spring底层有许多实现的类,比如AnnotationClassFilter(匹配指定注解)、TrueClassFilter(全部匹配)、AspectJExpressionPointcut(Aspect表达式匹配,APO重要的组件)
实例:使用AnnotationClassFilter测试该类是否有 @Transactional 注解
checkInherited ,如果为false,那么只检查当前类是否有对应的注解,为true,那么会检查父类或者实现的接口存在,默认为false @Test
public void testAnnotationClassFilter(){
//指定checkInherited为true,会同时检查该类和父类及其实现的接口是否存在Transactional注解
AnnotationClassFilter annotationClassFilter = new AnnotationClassFilter(Transactional.class, true);
boolean matches = annotationClassFilter.matches(UserServiceImpl.class);
System.out.println(matches);
}
我们也可以自定义自己的ClassFilter, 只需要实现其中的接口方法即可,如下:
@Test
public void testCustomClassFilter(){
//自定义一个classFilter,判断指定的类是否是UserServiceImpl的接口或者父类或者同类
ClassFilter customFilter =cls-> cls.isAssignableFrom(UserServiceImpl.class);
boolean matches = customFilter.matches(UserService.class);
System.out.println(matches);
}
UnionClassFilter 【满足其中一个即返回true】、 IntersectionClassFilter 【必须满足所有的ClassFilter才返回true】 public static ClassFilter union(ClassFilter cf1, ClassFilter cf2) public static ClassFilter intersection(ClassFilter cf1, ClassFilter cf2)
@Test
public void testClassFilters(){
//类或者接口上必须有Transactional注解
AnnotationClassFilter annotationClassFilter = new AnnotationClassFilter(Transactional.class,false);
//类或者接口必须是UserServiceImpl的父类或者接口或者同类
ClassFilter customFilter =cls-> cls.isAssignableFrom(UserServiceImpl.class);
//返回unionFilter,只要满足上面的一个ClassFilter即返回true
ClassFilter unionFilter = ClassFilters.union(annotationClassFilter, customFilter);
//返回intersectionFilter,必须满足上面两个ClassFilter才会返回true
ClassFilter intersectionFilter = ClassFilters.intersection(annotationClassFilter, customFilter);
boolean u = unionFilter.matches(UserService.class);
boolean i = intersectionFilter.matches(UserService.class);
System.out.println(u);
System.out.println(i);
}
接口的实现类有很多,如 StaticMethodMatcher 【只支持静态匹配,两个参数的matchs】、 AspectJExpressionPointcut 【AOP重要组件】、 TrueMethodMatcher 【总是匹配】、 AnnotationMethodMatcher 【注解匹配】
实例如下:
@Test
public void testAnnotationMethodMatcher()throws NoSuchMethodException {
//检测方法上是否标注了Transactional注解,false指定了不检查当前类父类和接口
AnnotationMethodMatcher methodMatcher=new AnnotationMethodMatcher(Transactional.class,false);
Class cls=UserService.class;
Method method = cls.getDeclaredMethod("addUser", User.class);
//两个参数的mathces,三个参数的不支持【继承了StaticMethodMatcher】
boolean matches = methodMatcher.matches(method, cls);
System.out.println(matches);
}
UnionMethodMatcher类 【只要匹配一个即返回true】, IntersectionMethodMatcher 【】 BeforeAdvice 、 AfterAdvice 等 AbstractAspectJAdvice ,各种AspectJ的通知都会继承并拓展该类,其中封装了有关通知的全部信息,比如方法名称、方法Method对象、PointCut、Jpoint、pointCut表达式等等信息,其中最重要的一个方法就是 protected Object invokeAdviceMethodWithGivenArgs(Object[] args) ,该方法用于调用通知方法。 AspectJXxxAdvice ,继承抽象类 AbstractAspectJAdvice 。 AspectAfterAdvice 这个实现类,其中重要的方法就是invok,源码如下:
public Object invoke(MethodInvocation mi)throws Throwable {
try {
//先执行被增强的方法
return mi.proceed();
}
finally {
//再执行通知方法
invokeAdviceMethod(getJoinPointMatch(), null, null);
}
}
AspectJExpressionPointcutAdvisor
org.springframework.aop.framework.DefaultAopProxyFactory#createAopProxy
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.");
}
//如果是接口,创建JDK的动态代理
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
return new ObjenesisCglibAopProxy(config);
}
else {
//创建Cglib动态代理
return new JdkDynamicAopProxy(config);
}
}
public class ProxyFactoryTest{
/**
* 自定义一个BeforeAdvice
*/
public static class CustomBeforAdviceimplements MethodBeforeAdvice{
@Override
public void before(Method method, Object[] args, Object target)throws Throwable {
String name = method.getName();
if (StringUtils.equals(name,"addUser")){
System.out.println("在addUser之前执行");
}else{
System.out.println("other");
}
}
}
public static class Log{
public void before(){
System.out.println("在之前执行");
}
}
@Test
public void test1(){
UserService userService=new UserServiceImpl();
//创建proxyFactory
ProxyFactory factory = new ProxyFactory(userService);
//创建自定义的BeforeAdvice
MethodBeforeAdvice advice=new CustomBeforAdvice();
//将Advice添加到proxyFactory中
factory.addAdvice(advice);
//获取代理对象
UserService proxy = (UserService) factory.getProxy();
proxy.addUser(new User(""));
}
@Test
public void test2()throws NoSuchMethodException {
UserService userService=new UserServiceImpl();
//创建proxyFactory
ProxyFactory factory = new ProxyFactory(userService);
Class aspectCls=Log.class;
Method aspectMethod = aspectCls.getMethod("before");
//构建aspectJ表达式切入点
AspectJExpressionPointcut aspectJExpressionPointcut = new AspectJExpressionPointcut();
aspectJExpressionPointcut.setExpression("execution(* cn.tedu.demo.service.UserService.addUser(..))");
//创建AspectInstanceFactory(切面实例工厂)
AspectInstanceFactory aspectInstanceFactory=new SimpleAspectInstanceFactory(aspectCls);
AspectJMethodBeforeAdvice advice=new AspectJMethodBeforeAdvice(aspectMethod,aspectJExpressionPointcut,aspectInstanceFactory);
//创建Advisor,其中封装了Advice和Advisor
Advisor advisor = new AspectJPointcutAdvisor(advice);
ArrayList<Advisor> advisors = Lists.newArrayList(advisor);
//添加ExposeInvocationInterceptor到advisor中,这个不是必须的,但是使用AspectJ expression pointcut是必须的
AspectJProxyUtils.makeAdvisorChainAspectJCapableIfNecessary(advisors);
//将advisor添加到ProxyFactory中
factory.addAdvisors(advisors);
UserService proxy= (UserService) factory.getProxy();
proxy.addUser(new User("chen"));
}
}
@EnableAspectJAutoProxy 该注解中可以看出使用了 @Import(AspectJAutoProxyRegistrar.class) ,因此实际作用的类就是 AspectJAutoProxyRegistrar 。 @Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
ImportBeanDefinitionRegistrar AnnotationAutoProxyCreator
class AspectJAutoProxyRegistrarimplements ImportBeanDefinitionRegistrar{
/**
* 向容器中注入AnnotationAutoProxyCreator
*/
@Override
public void registerBeanDefinitions(
AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
//调用方法注册AnnotationAutoProxyCreator
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
//获取@EnableAspectJAutoProxy注解中两个属性的值
AnnotationAttributes enableAspectJAutoProxy =
AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
//判断注解属性的值
if (enableAspectJAutoProxy != null) {
if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}
}
}
SmartInstantiationAwareBeanPostProcessor
创建代理对象的代码如下:
org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#wrapIfNecessary
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey){
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
//如果为false,直接返回,不需要代理
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
//判断是否是基础的切面类
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
// 获取适用的Advisor
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
//创建代理对象
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
//org.springframework.aop.framework.autoproxy.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 = new ProxyFactory();
proxyFactory.copyFrom(this);
if (!proxyFactory.isProxyTargetClass()) {
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
else {
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
proxyFactory.addAdvisors(advisors);
proxyFactory.setTargetSource(targetSource);
customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
return proxyFactory.getProxy(getProxyClassLoader());
}
AbstractAdvisorAutoProxyCreator
ReflectiveAspectJAdvisorFactory 是其实现类,AOP中就是使用该类构造Advisor private List<Method> getAdvisorMethods(Class<?> aspectClass) public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory)
private final AdvisedSupport advised :其中封装了代理类的属性,其实就是一个ProxyFactory,包括目标类,目标方法、advisor等信息。 public Object invoke(Object proxy, Method method, Object[] args) :方法调用的类,实现了InvocationHandler的方法 Object invoke(MethodInvocation invocation) throws Throwable
mi.proceed() 这个方法,是责任链模式的重要方法。 @Override
public Object invoke(MethodInvocation mi)throws Throwable {
try {
//调用其他的拦截器【因为这个拦截器是在方法之后执行的】
return mi.proceed();
}
finally {
//最终调用通知方法
invokeAdviceMethod(getJoinPointMatch(), null, null);
}
}
proceed ,通过责任链的模式执行拦截器中的方法,和MethodInterceptor完美的诠释了责任链设计模式。源码如下:
public Object proceed()throws Throwable {
// 标记拦截器链执行的位置,初始值是-1,递归的结束条件
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
//拦截器都执行完成了,那么通过反射执行目标方法
return invokeJoinpoint();
}
//获取拦截器
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;
Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass());
if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) {
return dm.interceptor.invoke(this);
}
else {
return proceed();
}
}
else {
//调用拦截器的invoke方法
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
@Test
public void test1()throws Throwable {
//目标对象
UserService userService=new UserServiceImpl();
//新建一个ProxyFactory,创建代理
ProxyFactory factory = new ProxyFactory();
factory.setTarget(userService);
//设置接口,否则使用的是cglib代理
factory.setInterfaces(UserService.class);
//获取代理对象
Object proxy = factory.getProxy();
//切面
Class aspectCls=LogAspect.class;
//通知方法
Method aspectMethod=aspectCls.getDeclaredMethod("afterAdvice");
//切面对象
final Object aspectObj=new LogAspect();
//新建一个拦截器
MethodInterceptor afterInterceptor=new MethodInterceptor() {
@Override
public Object invoke(MethodInvocation invocation)throws Throwable {
CustomeInvocation ref=(CustomeInvocation)invocation;
try{
//执行其他的拦截器
return invocation.proceed();
}finally {
//最后执行切面的方法
ref.getAspectMethod().invoke(ref.getAspectObj(), ref.getAspectArgs());
// System.out.println("方法之后执行");
}
}
};
//创建拦截器链
List<Object> interceptors=new ArrayList<>();
interceptors.add(afterInterceptor);
Method targetMethod=UserService.class.getMethod("addUser", User.class);
Object[] args=new Object[]{new User("陈加兵")};
CustomeInvocation invocation = new CustomeInvocation(proxy, userService, targetMethod, args, UserService.class,interceptors,aspectCls,aspectMethod,aspectObj,new Object[]{});
invocation.proceed();
}
/**
* 自定义一个Invocation,因为ReflectiveMethodInvocation是spring内部使用的,构造方法protected
*/
public static class CustomeInvocationextends ReflectiveMethodInvocation{
private Method aspectMethod;
private Class aspcetCls;
private Object aspectObj;
private Object[] aspectArgs;
/**
* @param proxy 代理
* @param target 目标对象
* @param method 目标方法
* @param arguments 参数
* @param targetClass 目标类
* @param aspectMethod 通知方法
* @param aspctCls 切面类
* @param aspectObj 切面对象
* @param interceptorsAndDynamicMethodMatchers 拦截器
*/
public CustomeInvocation(Object proxy, Object target, Method method, Object[] arguments, Class<?> targetClass, List<Object> interceptorsAndDynamicMethodMatchers,Class aspctCls,Method aspectMethod,Object aspectObj,Object[] aspectArgs){
super(proxy, target, method, arguments, targetClass, interceptorsAndDynamicMethodMatchers);
this.aspectMethod=aspectMethod;
this.aspcetCls=aspctCls;
this.aspectObj=aspectObj;
this.aspectArgs=aspectArgs;
}
}
public class JDKDynamicProxy{
public static interface Subject{
int add(int a,int b);
}
public static class CustomSubjectimplements Subject{
@Override
public int add(int a, int b){
System.out.println("执行加法计算");
return a+b;
}
}
/**
* 自定义的InvocationHandler
*/
public static class CustomInvocationHandlerimplements InvocationHandler{
/**
* 目标对象
*/
private Object targetObject;
public CustomInvocationHandler(Object targetObject){
this.targetObject = targetObject;
}
/**
* @param proxy 代理对象
* @param method 真正执行的方法
* @param args 方法参数
* @return
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {
String methodName = method.getName();
if (methodName.equals("add")){
System.out.println("invok调用");
Object invoke = method.invoke(targetObject, args);
return invoke;
}
return null;
}
}
@Test
public void test(){
Subject subject=new CustomSubject();
CustomInvocationHandler customInvocationHandler = new CustomInvocationHandler(subject);
Subject proxy= (Subject) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(),new Class[]{Subject.class}, customInvocationHandler);
int count = proxy.add(1, 2);
System.out.println(count);
}
}