探索小游戏引流的有效策略与未来发展趋势
883
2022-10-07
Spring(八)jdk动态代理(AOP简单实现)
说明
jdk动态代理就是对“装饰者”设计模式的简化。使用前提:必须要有接口
编写过程:
1.目标类:接口+实现类 2.切面类:用于存放通知。 3.工厂类:编写工厂生成代理 4.测试 UserService 接口 三个方法
public interface UserService { public void addUser(); public void updateUser(); public void deleteUser();}
UserService 实现类,实现了三个方法
public class UserServiceImpl implements UserService @Override public void addUser() { System.out.println("UserServiceDaoImpl addUser"); } @Override public void updateUser() { System.out.println("UserServiceDaoImpl updateUser"); } @Override public void deleteUser() { System.out.println("UserServiceDaoImpl deleteUser"); }}
切面类,共两个方法,before和end。希望在目标类的方法运行前后各调用一次。
public class MyAspect { public void before(){ System.out.println("before"); } public void after(){ System.out.println("after"); }}
工厂类,用于生成代理。 其中代理类的作用就是将目标类(切入点)和切面类(通知)结合。
import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;public class MyProxyFactory public static Object createUserService() { //目标类 final UserService userServiceDao = new UserServiceImpl(); //切面类 final MyAspect myAspect = new MyAspect(); //代理类 Object proxy = Proxy.newProxyInstance(MyProxyFactory.class .getClassLoader(), userServiceDao.getClass().getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object obj = null; //前方法 myAspect.before(); //执行目标类的方法 obj = method.invoke(userServiceDao, args); //后方法 myAspect.after(); return obj; } }); return
其中Proxy.newProxyInstance有三个参数。
arg1:loader,类加载器,动态代理类,运行时创建,任何类都需要类加载器加载到内存。一般使用当前类.class.getClassLoader();也可以使用目标实例.getClass().getClassLoader()arg2:代理类要实现的所有接口。目标类例.getClass().getInterfaces();arg3:InvocationHandler处理类,接口必须进行实现。一般采用匿名内部实现。提供的invoke方法。代理类的每一个方法执行都会调用一次invoke。invoke也有三个参数(Object proxy:代理对象, Method method:代理对象当前执行的方法,Object[] args:当前执行方法的参数)。我们可以通过method.getName来为不同的方法实现不同的功能。
测试类
public class Test { @org.junit.Test public void testProxy(){ UserService userService=(UserService) MyProxyFactory.createUserService(); userService.addUser(); userService.updateUser(); userService.deleteUser(); }}
运行结果
我们可以看到虽然我们调用的UserService对象,但是在每个方法执行的前后都有输出before和after。所以我们使用工厂类实现了jdk动态代理。
我们其实可以这样理解jdk动态代理。
在底层我们在调用代理类的方法时,它会执行invoke方法。
代理类本身没有什么功能,它只是把所有的功能组合在一起。
代理类addUser(){ invoke(this,addUser,[]);}updateUser(){ invoke(this,updateUser,[]);}deleteUser(){ invoke(this,deleteUser,[]);}
你看懂了吗? 上面说了 我们可以通过method.getName来为特定的方法实现特定的功能。那么我们只为addUser方法执行before和after方法。
我们修改代理类的invoke方法
@Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object obj = null; if("addUser".equals(method.getName())){ //前方法 myAspect.before(); //执行目标类的方法 obj = method.invoke(userServiceDao, args); //后方法 myAspect.after(); }else{ obj = method.invoke(userServiceDao, args); } return
执行结果:
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~