11-25 程宗武
11-25 Spring03
1.AOP
AOP: 面向切面编程。把重复的代码抽取,在需要使用的地方,使用动态代理的技术,对原有的方法进行增强
1.1 动态代理
字节码随用随创建,随用随加载。
1.1.1基于接口的动态代理
JDK的Proxy类 ,要求被代理类最少实现一个接口
public class Actor implements IActor {
public void basicAct(float money) {
System.out.println("成龙基本演出收入:" + money);
}
public void dangerAct(float money) {
System.out.println("成龙危险演出收入:" + money);
}
public static void main(String[] args) {
final Actor actor = new Actor();
//这里因为传入的是被代理的是接口类型,所以也要用接口类型的来接收 但实际执行的是实现类中的方法
IActor proxyInstance = (IActor) Proxy.newProxyInstance(actor.getClass().getClassLoader(), actor.getClass().getInterfaces(), new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
String name = method.getName();
Float money = (Float) args[0];
Object returnValue = null;
if ("basicAct".equalsIgnoreCase(name)) {
if (money >= 5000) {
returnValue = method.invoke(actor, money / 2);
}
}
if ("dangerAct".equalsIgnoreCase(name)) {
if (money >= 10000) {
returnValue = method.invoke(actor, money / 2);
}
}
return null;
}
});
proxyInstance.basicAct(5000);
proxyInstance.basicAct(10000);
}
}
1.1.2基于子类的动态代理
第三方的 CGLib,要求被代理类不能用 final 修饰的类(最终类)。
maven的坐标
<dependencies>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>2.1_3</version>
</dependency>
</dependencies>
public class Actor2 {
public void basicAct(float money) {
System.out.println("李连杰基本演出收入:" + money);
}
public void dangerAct(float money) {
System.out.println("李连杰危险演出收入:" + money);
}
public static void main(String[] args) {
final Actor2 actor2 = new Actor2();
//这里直接用本类类型来接收
Actor2 proxyActor = (Actor2) Enhancer.create(actor2.getClass(), new MethodInterceptor() {
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
String name = method.getName();
Float money = (Float) args[0];
Object returnValue = null;
if ("basicAct".equalsIgnoreCase(name)) {
if (money >= 5000) {
returnValue = method.invoke(actor2, money / 2);
}
}
if ("dangerAct".equalsIgnoreCase(name)) {
if (money >= 10000) {
returnValue = method.invoke(actor2, money / 2);
}
}
return returnValue;
}
});
proxyActor.basicAct(5000);
proxyActor.dangerAct(10000);
}
}
注: 在执行被代理类中的任何方法时,都会经过这个动态代理处理过后的方法 例: public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 相当于一个拦截器。然后对被代理类中相应的方法进行处理过后,再执行。
近期评论