博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
spring introduction aop
阅读量:6006 次
发布时间:2019-06-20

本文共 4345 字,大约阅读时间需要 14 分钟。

hot3.png

众所周知,spring aop中一个advisor=advice or methodinterceptor + pointcut,之后将不同的advisor调用ProxyFactory的addAdvisor方法添加进去并排序(顺序特别重要,在最新的源码里是需要实现PriorityOrdered接口或者使用@Order注解来实现),最后调用ProxyFactory的getProxy方法得到增强,在看spring源码的时候偶尔注意到了一系列introduction和mixin的概念,附上一篇非常nice的博文:http://www.javalobby.org/java/forums/t45691.html

废话不多说,上代码:

package com.rabbit.spring.aop.introduction;import org.springframework.aop.IntroductionAdvisor;import org.springframework.aop.framework.ProxyFactory;public class IntroductionExample {	public static void main(String[] args) {		TargetBean target = new TargetBean();		target.setName("Ethan");				IntroductionAdvisor advisor = new IsModifiedAdvisor();				ProxyFactory pf = new ProxyFactory();		pf.setTarget(target);		pf.addAdvisor(advisor);		pf.setOptimize(true);				TargetBean proxy = (TargetBean) pf.getProxy();		IsModified proxyInterface = (IsModified) proxy;				System.out.println("is target bean " + (proxy instanceof TargetBean));		System.out.println("is ismodified " + (proxy instanceof IsModified));		System.out.println("changed? " + proxyInterface.isModified());				proxy.setName("Zhang");		System.out.println("changed? " + proxyInterface.isModified());		proxy.setName("Li");		System.out.println("changed? " + proxyInterface.isModified());	}}

package com.rabbit.spring.aop.introduction;public interface IsModified {	boolean isModified();}

package com.rabbit.spring.aop.introduction;import org.springframework.aop.support.DefaultIntroductionAdvisor;public class IsModifiedAdvisor extends DefaultIntroductionAdvisor {	/**	 * 	 */	private static final long serialVersionUID = 1L;	public IsModifiedAdvisor() {		super(new IsModifiedMixin());	}}

package com.rabbit.spring.aop.introduction;import java.lang.reflect.Method;import java.util.Map;import java.util.concurrent.ConcurrentHashMap;import org.aopalliance.intercept.MethodInvocation;import org.springframework.aop.support.DelegatingIntroductionInterceptor;public class IsModifiedMixin extends DelegatingIntroductionInterceptor implements IsModified {	/**	 * 	 */	private static final long serialVersionUID = 1L;	private boolean isModified = false;    private Map
methodCache = new ConcurrentHashMap<>(); @Override public boolean isModified() { return isModified; } public Object invoke(MethodInvocation invocation) throws Throwable { if (!isModified) { if ((invocation.getMethod().getName().startsWith("set")) && (invocation.getArguments().length == 1)) { Method getter = getGetter(invocation.getMethod()); if (getter != null) { Object newVal = invocation.getArguments()[0]; Object oldVal = getter.invoke(invocation.getThis(), null); if((newVal == null) && (oldVal == null)) { isModified = false; } else if((newVal == null) && (oldVal != null)) { isModified = true; } else if((newVal != null) && (oldVal == null)) { isModified = true; } else { isModified = (!newVal.equals(oldVal)); } } } } return super.invoke(invocation); } private Method getGetter(Method setter) { Method getter = methodCache.get(setter); if (getter != null) { return getter; } String getterName = setter.getName().replaceFirst("set", "get"); try { getter = setter.getDeclaringClass().getMethod(getterName, (Class
[]) null); methodCache.put(setter, getter); return getter; } catch (NoSuchMethodException ex) { return null; } }}

package com.rabbit.spring.aop.introduction;public class TargetBean {	/**	 * @return the name	 */	public String getName() {		return name;	}	/**	 * @param name the name to set	 */	public void setName(String name) {		this.name = name;	}	private String name;	}

运行结果:

is target bean true

is ismodified true

changed? false

changed? true

changed? true

github地址:https://github.com/stillotherguy/javaopensource/tree/master/src/main/java/com/rabbit/spring/aop/introduction

可以自己copy一份运行一下,要想知道其中奥秘,spring aop源码是必须了解的,以后有空写一下!

转载于:https://my.oschina.net/stillotherguy/blog/401951

你可能感兴趣的文章
全球.COM域名注册量统计:2月增超29万域名
查看>>
11月微博博客日均覆盖数TOP10:网易博客升至第七
查看>>
6月28日全球域名注册商(国际域名)保有量及市场份额
查看>>
Android热修复升级探索——代码修复冷启动方案
查看>>
Dwz做前台页面,Jfinal后台使用前台下载excel【两种解决方案】
查看>>
Android 部分截图分享
查看>>
脚本实现mysql 备份
查看>>
linux 知识点整理,从虚拟机安装到常用开发软件在linux上的安装命令
查看>>
关于WinGate代理服务器的概述
查看>>
socket, nio socket 及nio socket框架MINA总结 (转)
查看>>
R语言笔记
查看>>
linux “洪ping”
查看>>
健康传说网简介
查看>>
学校宿舍的深夜之思考
查看>>
一大型工厂网络规划方案
查看>>
计算机网络之面试常考 转
查看>>
高级VIM
查看>>
积攒了这么多技术干货,总有一款适合你
查看>>
bed文件
查看>>
修改linux默认栈大小
查看>>