- 概念
AOP为Aspect Oriented Programming的缩写,意味:面向切面编程。 与IOC一样,是一种思想。
- 作用
对业务逻辑进行分离,降低耦合度,提高程序的重用性,提高开发效率。
- JDK动态代理(接口代理)
弱点:JDK动态代理是基于接口的, 必须有接口。
模拟:
1. 新建接口类
package org.spring.exampleAOP;
public interface People {
void Shoot();
}
2. 新建实现类
package org.spring.exampleAOP;
public class Sadamu implements People {
public Sadamu() {
}
@Override
public void Shoot() {
System.out.println("萨达姆开枪了");
}
}
3. 新建代理类
package org.spring.exampleAOP;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class JdkProxyUtils {
public static Object getProxy(final Object obj) {
return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//代理要做的事
System.out.println("记录日志 Befor:" + obj.toString() + " Method: " + method.getName());
method.invoke(obj, args); //执行原对象方法
System.out.println("记录日志 After:" + obj.toString() + " Method: " + method.getName());
return proxy;
}
});
}
}
4. 测试
package org.spring.exampleAOP;
public class Test {
public static void main(String[] args) {
//jdk的动态代理是基于接口
People people = new Sadamu();
People ppeople = (People) JdkProxyUtils.getProxy(people); //传入值必须是接口
ppeople.Shoot();
}
}
测试结果:
记录日志 Befor:org.spring.exampleAOP.Sadamu@3764951d Method: Shoot
萨达姆开枪了
记录日志 After:org.spring.exampleAOP.Sadamu@3764951d Method: Shoot
Process finished with exit code 0
- Cglib代理(子类代理) 个人感觉是比JDK接口代理方便
1. 需要的jar包 asm.jar和cglib-2.1.3.jar
2. 新建子类代理类
package org.spring.exampleAOP;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.InvocationHandler;
import java.lang.reflect.Method;
public class CglibProxyUtils {
public static Object getProxy(Object obj){
return Enhancer.create(obj.getClass(), new InvocationHandler() {
@Override
public Object invoke(Object o, Method method, Object[] args) throws Throwable {
System.out.println("记录日志 Befor:" + obj.toString() + " Method: " + method.getName());
method.invoke(obj, args);
System.out.println("记录日志 After:" + obj.toString() + " Method: " + method.getName());
return obj;
}
});
}
}
3. 测试
package org.spring.exampleAOP;
public class Test {
public static void main(String[] args) {
//Cglib子类代理
Kazhafei kazhafei = new Kazhafei();
People pkazhafei = (People) CglibProxyUtils.getProxy(kazhafei); //传入的对象有没有接口都无所谓
pkazhafei.Shoot();
}
}