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...


  • 相关阅读:
    HDU 1850 Being a Good Boy in Spring Festival
    UESTC 1080 空心矩阵
    HDU 2491 Priest John's Busiest Day
    UVALive 6181
    ZOJ 2674 Strange Limit
    UVA 12532 Interval Product
    UESTC 1237 质因子分解
    UESTC 1014 Shot
    xe5 android listbox的 TMetropolisUIListBoxItem
    xe5 android tts(Text To Speech)
  • 原文地址:https://www.cnblogs.com/wugang/p/14232329.html
Copyright © 2011-2022 走看看