上篇中的自定义Advisor是实现的AbstractPointcutAdvisor,Advisor其实还有一个接口级别的IntroductionAdvisor

                   

这个好像用的很少,网上搜了一些资料,说是基于Class的增强,接口的功能扩展,在原有的功能上增加一些其他接口定义的方法,可以将当前代理对象向上转型,然后调用接口中的方法

这个功能暂时还不知道适用于什么场景

示例:

//定义一个some类,只有doSome方法
@Component
public class Some {
public void doSome() {
System.out.println("do some...");
};
}
//定义一个other接口,提供doOther功能
public interface IOther {
public void doOther();
}
//定义一个通知器
@Component
public class OtherIntroductionAdvisor extends DefaultIntroductionAdvisor { public OtherIntroductionAdvisor() {
super(new OtherIntroductionInterceptor());
} // createBean的时候判断bean是否需要被代理
@Override
public boolean matches(Class<?> clazz) {
//只代理some对象
boolean assignableFrom = clazz.isAssignableFrom(Some.class);
return assignableFrom;
}
}
//定义一个通知,要实现IOther接口
public class OtherIntroductionInterceptor implements IntroductionInterceptor, IntroductionInfo, IOther { //实现doOther方法
@Override
public void doOther() {
System.out.println("do other ...");
} //扩展功能的实现
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
//当前方法的声明类是否实现了需要拓展功能的接口
if (implementsInterface(invocation.getMethod().getDeclaringClass())) {
//调用this的此方法
return invocation.getMethod().invoke(this, invocation.getArguments());
}
return invocation.proceed();
} @Override
public boolean implementsInterface(Class<?> ifc) {
Class<?>[] interfaces = this.getInterfaces();
for (Class clazz : interfaces) {
if (ifc.isInterface() && ifc.isAssignableFrom(clazz)) {
return true;
}
}
return false;
} @Override
public Class<?>[] getInterfaces() {
return new Class[] {IOther.class};
}
}

在创建代理对象时,将拓展功能的接口set进去,所以代理对象上转型才不会报错

org.springframework.aop.framework.CglibAopProxy#getProxy(java.lang.ClassLoader)

@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isDebugEnabled()) {
logger.debug("Creating CGLIB proxy: target source is " + this.advised.getTargetSource());
} try {
Class<?> rootClass = this.advised.getTargetClass();
Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy"); Class<?> proxySuperClass = rootClass;
if (ClassUtils.isCglibProxyClass(rootClass)) {
proxySuperClass = rootClass.getSuperclass();
Class<?>[] additionalInterfaces = rootClass.getInterfaces();
for (Class<?> additionalInterface : additionalInterfaces) {
this.advised.addInterface(additionalInterface);
}
} // Validate the class, writing log messages as necessary.
validateClassIfNecessary(proxySuperClass, classLoader); // Configure CGLIB Enhancer...
Enhancer enhancer = createEnhancer();
if (classLoader != null) {
enhancer.setClassLoader(classLoader);
if (classLoader instanceof SmartClassLoader &&
((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
enhancer.setUseCache(false);
}
}
enhancer.setSuperclass(proxySuperClass);
// 获取接口信息并且set到代理对象的接口中
enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
enhancer.setStrategy(new ClassLoaderAwareUndeclaredThrowableStrategy(classLoader)); Callback[] callbacks = getCallbacks(rootClass);
Class<?>[] types = new Class<?>[callbacks.length];
for (int x = 0; x < types.length; x++) {
types[x] = callbacks[x].getClass();
}
// fixedInterceptorMap only populated at this point, after getCallbacks call above
enhancer.setCallbackFilter(new ProxyCallbackFilter(
this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
enhancer.setCallbackTypes(types); // Generate the proxy class and create a proxy instance.
return createProxyClassAndInstance(enhancer, callbacks);
}
catch (CodeGenerationException | IllegalArgumentException ex) {
throw new AopConfigException("Could not generate CGLIB subclass of " + this.advised.getTargetClass() +
": Common causes of this problem include using a final class or a non-visible class",
ex);
}
catch (Throwable ex) {
// TargetSource.getTarget() failed
throw new AopConfigException("Unexpected AOP exception", ex);
}
}

3.AOP中的IntroductionAdvisor的更多相关文章

  1. Spring AOP中定义切点(PointCut)和通知(Advice)

    如果你还不熟悉AOP,请先看AOP基本原理,本文的例子也沿用了AOP基本原理中的例子.切点表达式 切点的功能是指出切面的通知应该从哪里织入应用的执行流.切面只能织入公共方法.在Spring AOP中, ...

  2. 正确理解Spring AOP中的Around advice

    Spring AOP中,有Before advice和After advice,这两个advice从字面上就可以很容易理解,但是Around advice就有点麻烦了. 乍一看好像是Before ad ...

  3. Spring AOP中的动态代理

    0  前言 1  动态代理 1.1 JDK动态代理 1.2 CGLIB动态代理 1.2.1 CGLIB的代理用法 1.2.2 CGLIB的过滤功能 2  Spring AOP中的动态代理机制 2.1  ...

  4. Spring AOP高级——源码实现(2)Spring AOP中通知器(Advisor)与切面(Aspect)

    本文例子完整源码地址:https://github.com/yu-linfeng/BlogRepositories/tree/master/repositories/Spring%20AOP%E9%A ...

  5. 笔记13 AOP中After和AfterReturning的区别

    AOP中 @Before @After @AfterThrowing@AfterReturning的执行顺序 public Object invoke(Object proxy, Method met ...

  6. spring aop中pointcut表达式完整版

    spring aop中pointcut表达式完整版 本文主要介绍spring aop中9种切入点表达式的写法 execute within this target args @target @with ...

  7. Spring AOP中的JDK和CGLib动态代理哪个效率更高?

    一.背景 今天有小伙伴面试的时候被问到:Spring AOP中JDK 和 CGLib动态代理哪个效率更高? 二.基本概念 首先,我们知道Spring AOP的底层实现有两种方式:一种是JDK动态代理, ...

  8. 转:Spring AOP中的动态代理

    原文链接:Spring AOP中的动态代理 0  前言 1  动态代理 1.1 JDK动态代理 1.2 CGLIB动态代理 1.2.1 CGLIB的代理用法 1.2.2 CGLIB的过滤功能 2  S ...

  9. Spring AOP 中@Pointcut的用法

    Spring Aop中@pointCut的用法,格式:execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? nam ...

随机推荐

  1. SQL脚本优化

    1.创建索引一.要尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引   (1)在经常需要进行检索的字段上创建索引,比如要按照表字段username进行检索,那么就应 ...

  2. 轻量化模型之MobileNet系列

    自 2012 年 AlexNet 以来,卷积神经网络在图像分类.目标检测.语义分割等领域获得广泛应用.随着性能要求越来越高,AlexNet 已经无法满足大家的需求,于是乎各路大牛纷纷提出性能更优越的 ...

  3. 原生js为页面添加爱心特效和判断手机端还是电脑端登录

    <!-- 为页面添加爱心特效 --> <script type="text/javascript"> (function (window, document ...

  4. Struts2自定义标签重写(转)

    TagSupport的学习 1 TagSupport与BodyTagSupport的区别 TagSupport与BodyTagSupport的区别主要是标签处理类是否需要与标签体交互,如果不需要交互的 ...

  5. ftp服务器终端登录后乱码处理方法

    首先在windows上用资源管理器登录看看会不会乱码,如果不会,说明是GBK编码 因为windows默认是GBK(936),linux默认(UTF-8) 因为FTP服务器我们修改不了,如果用linux ...

  6. JSON 对象和字符串

    JSON 对象和字符串 粘贴自:https://www.cnblogs.com/cstao110/p/3762056.html Q:什么是"JSON字符串",什么是"JS ...

  7. 《wifi加密破解论文》翻译介绍-wifi不再安全

    前言 wifi的加密协议WPA2已经被破解,影响范围包括所有支持wifi的设备,包括Android,Linux,Apple,Windows,OpenBSD,联发科技,Linksys等.其中对Andro ...

  8. CSS样式设置小技巧

    1.水平居中设置 行内元素居中设置:如果被设置元素为文本.图片等行内元素时,水平居中是通过给父元素设置 text-align:center 来实现的.代码示例如下: HTML代码 <body&g ...

  9. C# 操作服务命令

    安装服务 @echo.服务启动...... @echo off @sc create 服务名称 binPath= " exe地址" @net start 服务名称 @sc conf ...

  10. [2019牛客多校第二场][A. Eddy Walker]

    题目链接:https://ac.nowcoder.com/acm/contest/882/A 题目大意:圆上有\(n\)个点,标号从\(0\)到\(n-1\),初始一个人在点\(0\),每次会等概率向 ...