标签:
相关概念:
Aspect:切面切入系统的一个个切面,列如AOP实际应用中的权限管理技术,权限管理就是一个切面,一个Aspect
PointCut:真正被切入的地方
JointPoint:链接点,就是被切入的位置
Advice:切面在某个点执行的动作
Spring实现AOP技术有2种基本方法:动态代理/CGLB(动态字节码增强技术)
1. 动态代理
实现InvocationHandler接口、Proxy.newProxyInstanc()方法
使用动态代理时要创建一个中间对象,将被代理对象注入到中将对象(IOC),中间对象实现InvocationHandler接口,中将对象实现被代理对象的方法,在调用的前后自然可以加上一些逻辑,并且Proxy.newProxyInstance()方法能够使用中间对象来生成代理对象,插入的那些前后逻辑就是切面代码。这里有个Demo(这个demo转载于推酷网)
被代理对象实现的接口:
public interface UserService {
public void addUser(User user);
publicUser getUser(int id);
}
被代理对象:
public class UserServiceImpl implementsUserService {
public void addUser(User user) {
System.out.println("add user into database.");
}
public User getUser(int id) {
User user = newUser();
user.setId(id);
System.out.println("getUser from database.");
return user;
}
}
代理中间类:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class ProxyUtil implementsInvocationHandler {
private Object target; //被代理的对象
public Object invoke(Object proxy,Method method, Object[] args) throws Throwable {
System.out.println("do sth before....");
Object result = method.invoke(target, args);
System.out.println("do sth after....");
returnresult;
}
ProxyUtil(Object target){
this.target= target;
}
public Object getTarget() {
returntarget;
}
public void setTarget(Object target) {
this.target= target;
}
}
测试:
import java.lang.reflect.Proxy;
import net.aazj.pojo.User;
public classProxyTest {
public static void main(String[] args){
Object proxyedObject = new UserServiceImpl(); //被代理的对象
ProxyUtil proxyUtils = new ProxyUtil(proxyedObject);
//生成代理对象,对被代理对象的这些接口进行代理:UserServiceImpl.class.getInterfaces()
UserService proxyObject = (UserService)Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),
UserServiceImpl.class.getInterfaces(),proxyUtils);
proxyObject.getUser(1);
proxyObject.addUser(new User());
}
}
执行结果:
do sth before....
getUser from database.
do sth after....
do sth before....
add userinto database.
do sth after....
2. CGLIB ( code generate library 字节码生成技术
针对类来实现,对指定的类生成一个子类,覆盖方法并对其增强,加入切面代码。以下Demo转载于:http://www.cnblogs.com/jqyp/archive/2010/08/20/1805041.html
Demo:
package net.aazj.aop;
import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
publicclass CGProxy implementsMethodInterceptor{
private Object target; //被代理对象
public CGProxy(Object target){
this.target = target;
}
public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy proxy) throws Throwable {
System.out.println("do sth before....");
Object result = proxy.invokeSuper(arg0, arg2);
System.out.println("do sth after....");
return result;
}
public Object getProxyObject() {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(this.target.getClass()); //设置父类
//设置回调
enhancer.setCallback(this); //在调用父类方法时,回调 this.intercept()
//创建代理对象
return enhancer.create();
}
}
publicclassCGProxyTest {
publicstaticvoid main(String[] args){
Object proxyedObject = new UserServiceImpl(); //被代理的对象
CGProxy cgProxy = new CGProxy(proxyedObject);
UserService proxyObject = (UserService) cgProxy.getProxyObject();
proxyObject.getUser(1);
proxyObject.addUser(new User());
}
}
输出结果:
do sth before....
getUser from database.
do sth after....
do sth before....
adduserinto database.
do sth after....
标签:
原文地址:http://blog.csdn.net/qq_31573519/article/details/51351642