定义了一个自定义注解,可以作用在方法和类型,
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE,ElementType.METHOD}) // 可以作用在类上、方法上
public @interface DS {
String value() default "";
}
但是有一个问题,单独给类加上面的注解并没有触发AOP,而在方法上使用上面的注解可以触发AOP。这个是什么原因??
@Aspect
@Component
public class DynamicDataSourceAspect {
@Before("@annotation(DS)")
public void beforeSwitchDS(JoinPoint point){
Class<?> target1 = point.getTarget().getClass();
MethodSignature signature = (MethodSignature) point.getSignature();
// 默认使用目标类型的注解,如果没有则使用其实现接口的注解
for (Class<?> clazz : target1.getInterfaces()) {
resolveDataSource(clazz, signature.getMethod());
}
resolveDataSource(target1, signature.getMethod());
}
@After("@annotation(DS)")
public void afterSwitchDS(JoinPoint point){
DataSourceContextHolder.clearDB();
}
/**
* 提取目标对象方法注解和类型注解中的数据源标识 * * @param clazz
* @param method
*/
private void resolveDataSource(Class<?> clazz, Method method) {
try {
Class<?>[] types = method.getParameterTypes();
// 默认使用类型注解-也就是使用定义类上面的注解
if (clazz.isAnnotationPresent(DS.class)) {
DS source = clazz.getAnnotation(DS.class);
System.out.println("类上的注解"+source.value());
DataSourceContextHolder.setDB(source.value());
}
// 方法注解可以覆盖类型注解-也就是使用方法上的注解去替换类上面的注解
Method m = clazz.getMethod(method.getName(), types);
if (m != null && m.isAnnotationPresent(DS.class)) {
DS source = m.getAnnotation(DS.class);
System.out.println("方法上的注解"+source.value());
DataSourceContextHolder.setDB(source.value());
}
} catch (Exception e) {
}
}
}
上次debug看了下这个鬼东西,当你用@annotation去做拦截的时候,查找注解,他直接从方法上面查找的,所以你写直接到类上没啥用

入口代码:org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.wrapIfNecessary,这个方法,当你类和方法上写注解,结果是不同的
最关键匹配的地方:


org.aspectj.weaver.patterns.ExactAnnotationTypePattern.matches(annotated,parameterAnnotations)
annotated的实现类此时是ReflectionBasedResolvedMemberImpl,