zoukankan      html  css  js  c++  java
  • Java通过反射动态代理实现AOP

    假设已有如下接口和接口的实现类。

    public interface UserService {
    	void addUser();
    	void updateUser();
    	void deleteUser();
    }
    public class UserServiceImpl implements UserService {
    
    	@Override
    	public void addUser() {
    		System.out.println("add user");
    	}
    
    	@Override
    	public void updateUser() {
    		System.out.println("update user");
    	}
    
    	@Override
    	public void deleteUser() {
    		System.out.println("delete user");
    	}
    
    }

    在此基础上,不修改源代码,在调用UserServiceImpl的实例方法前后,输出其他的信息。

    首先,创建一个切面类MyAspect。

    public class MyAspect {
    	public void befor() {
    		System.out.println("befor...");
    	}
    	
    	public void after() {
    		System.out.println("after...");
    	}
    }

    再创建一个类,用来获取目标类的代理类。

    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    public class MyBeanFactroy {
    	public static UserService CreateUserService() {
    		// 第一步
    		final UserService userService = new UserServiceImpl();
    		// 第二步
    		final MyAspect myAspect = new MyAspect();
    		// 第三步
    		UserService proxyService = (UserService) Proxy.newProxyInstance(MyBeanFactroy.class.getClassLoader(),
    				new Class[] { UserService.class }, new InvocationHandler() {
    
    					@Override
    					public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                                                    //第五步
    						myAspect.befor();
                                                    //第四步
    						Object obj = method.invoke(userService, args);
                                                    //第五步
    						myAspect.after();
    
    						return obj;
    					}
    				});
    
    		return proxyService;
    	}
    }

    第一步:声明目标类

    第二步:声明切面类

    第三步:通过,Proxy.newProxyInstance,创建代理实例。

        参数1:loader ,类加载器,动态代理类 运行时创建,任何类都需要类加载器将其加载到内存。一般情况:当前类.class.getClassLoader();

        参数2:Class[] interfaces 代理类需要实现的所有接口

    * 方式1:目标类实例.getClass().getInterfaces()  ;注意:只能获得自己接口,不能获得父元素接口

    * 方式2:new Class[]{UserService.class}   

        参数3:实现InvocationHandler接口的实例类(我这里使用匿名对象的写法),重写invoke方法

    第四步:通过invoke方法,反射调用目标类的方法

    第五步:调用切面了的方法。


    用junit调用试试看。

    import org.junit.Test;
    
    public class MyTest {
    
    	@Test
    	public void test1() {
    		UserService userService = MyBeanFactroy.CreateUserService();
    		userService.addUser();
    		userService.updateUser();
    		userService.deleteUser();
    	}
    
    }

    输出结果:

    befor...
    add user
    after...
    befor...
    update user
    after...
    befor...
    delete user
    after...


  • 相关阅读:
    非常不错的学习网站——技术胖
    Vue中使用mescroll.js实现下拉刷新
    2020.10.07【NOIP提高A组】模拟
    2020.10.06【NOIP提高A组】模拟 总结
    2020.09.19【NOIP提高A组】模拟
    2020.09.12【NOIP提高A组】模拟
    GMOJ 4417. 【HNOI2016模拟4.1】神奇的字符串 题解
    上下界网络流学习笔记
    GMOJ 3571. 【GDKOI2014】内存分配 题解
    [模板]人工栈
  • 原文地址:https://www.cnblogs.com/wugang/p/14232329.html
Copyright © 2011-2022 走看看