利用反射生成JDK的动态代理,也就是AOP中的AOP代理,代替目标对象,从而在代码中织入增强。
定义代理接口
由于JDKf动态代理只能为接口创建动态代理,故先定义接口,假定我们需要对数据的Save方法添加事务处理,我们有一个UserDao接口,里面有一个Save方法,代码如下:
1
2
3
|
public interface UserDao { public void save(); } |
定义代理实现
下面具体来实现接口定义的Save方法,我们采用下面的代码来实现。
1
2
3
4
5
6
7
8
|
public class UserDaoImpl implements UserDao { @Override public void save() { System.out.println( "I am save user...." ); } } |
定义增强代码
我们有如下的操作,在保存用户之前打开事务,在保存用户之后提交事务,在增强代码中定义两个方法before()和after(),分别用在save()方法的执行开始之前和执行之后。
1
2
3
4
5
6
7
8
|
public class UserTx { public void before(){ System.out.println( "before save....." ); } public void after(){ System.out.println( "after save......" ); } } |
定义Invocation handler
之所以要定义handler是因为执行动态代理时,实际执行的是handler里面的invoke()方法,这样的话,我们在invoke()方法里面自定义方法的内容,从而就达到了代理和增强的逻辑和效果。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
public class UserDaoInvocationHandler implements InvocationHandler { / 需要代理的对象 / private Object proxyObj; / 指定我们需要代理的对象 @param proxyObj */ public void setProxyObj(Object proxyObj) { this .proxyObj = proxyObj; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { UserTx tx = new UserTx(); tx.before(); Object resultObj = method.invoke(proxyObj, args); tx.after(); return resultObj; } } |
测试结果
上面已经定义好所有的东西,我们就实际来动态代理我们指定的对象,用代理后的对象来执行我们要执行的方法,验证是否代理成功。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
import java.lang.reflect.Proxy; public class ProxyTst { public static void main(String[] args) { // proxy object UserDao target = new UserDaoImpl(); // invocation handler UserDaoInvocationHandler handler = new UserDaoInvocationHandler(); handler.setProxyObj(target); // proxy UserDao targeted = (UserDao) Proxy.newProxyInstance( target.getClass().getClassLoader(), target.getClass().getInterfaces(), handler); // execute proxyed object targeted.save(); } } |
执行上面的代码之后我们可以在控制台看见如下的输出,证明UserDao已经被成功代理,同时我们也为我们的程序成功的添加了事务功能。
1
2
3
|
before save..... I am save user.... after save...... |
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。
原文链接:http://www.jianshu.com/p/561ecef01bc6