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