假设已有如下接口和接口的实现类。
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...