/**
* 引入增强(Introduction Advice)的概念:
* 一个Java类,没有实现X接口,在不修改Java类的情况下,使其具备X接口的功能
*/
/**
* 定义一个接口
*/
interface IX {
void xx();
}
/**
* 定义目标类,在不实现IX的情况下,拥有IX的所有功能
*/
static class Person {
void run() {
System.out.println("run");
}
void say() {
System.out.println("say");
}
}
/**
* 定义一个通知,这个通知会应用到目标类,执行目标方法是会被invoke方法拦截
*/
static class IOtherInteIntroductionInterceptor implements IntroductionInterceptor, IX {
/**
* 判断调用的方法是否为指定类中的方法
* 如果Method代表了一个方法 那么调用它的invoke就相当于执行了它代表的这个方法
*/
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
// 核心在这个方法,当前类是拦截器,执行代理类的目标方法都会被这个方法拦截
// 只需要这个对这个方法进行逻辑处理就OK
System.out.println("增强增强");
// 判断当前正在执行的目标方法类是不是实现了要增强的接口
boolean son = this.implementsInterface(invocation.getMethod().getDeclaringClass());
// 如果实现了要增强的接口,那么就代表了要增强,执行增强方法
if (son) {
return invocation.getMethod().invoke(this, invocation.getArguments());
}
// 如果没有实现增强接口,表示是执行的是一个非增强的,按照常规拦截器的逻辑,直接放行到下一个拦截器就可以
// 通过拦截器链来最终执行目标方法
return invocation.proceed();
}
/**
* 判断clazz是否为给定接口IOtherBean的实现
*/
@Override
public boolean implementsInterface(Class clazz) {
return clazz.isAssignableFrom(IX.class);
}
/**
* 增强方法
*/
@Override
public void xx() {
System.out.println("给人贴标签 doOther...");
}
}
// 创建代理对象
public static void main(String[] args) {
ProxyFactory factory = new ProxyFactory(new Person());
// 强制私用CGLIB 以保证我们的Person方法也能正常调用
factory.setProxyTargetClass(true);
// 创建我们自定义的通知
Advice advice = new IOtherInteIntroductionInterceptor();
// 定义切面,包含了通知和需要对目标类附加的接口功能
Advisor advisor = new DefaultIntroductionAdIOtherIntevisor(advice, () -> new Class[]{IX.class});
factory.addAdvisor(advisor);
Object proxy = factory.getProxy();
IX x= (IX) proxy;
x.xx();
// Person本身自己的方法 也得到了保留
Person p = (Person) proxy;
p.run();
p.say();
}
Spring另一种增强的切面IntroductionAdvisor
于 2024-03-02 23:12:07 首次发布