Spring AOP(二) AOP的底层实现

AOP的底层实现:通过二种动态代理实现的,一种是jdk动态代理,另一种是cglib的动态代理
对于不使用接口的业务类,无法使用Jdk的动态代理;
cglib采用非常底层字节码技术,可以为一个类创建子类,解决无接口代理问题

//先save方法添加权限验证
//JDK动态代理
public interface UserDao{
	public void save(){
	}
}

public class UserDaoImpl implements UserDao{
	public void save(){
		System.out.println("save.....");
	}
}

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class MyJdkProxy implements InvocationHandler {
    private UserDao userDao;

    public MyJdkProxy(UserDao userDao){
        this.userDao=userDao;
    }

    public Object createProxy(){//创建代理类
        Object proxy= Proxy.newProxyInstance(userDao.getClass().getClassLoader(),
                userDao.getClass().getInterfaces(),this);
        return proxy;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        if("save".equals(method.getName())){
            System.out.println("权限校验...");
            return method.invoke(userDao,args);
        }
        return method.invoke(userDao,args);
    }
}

import org.junit.Test;

public class SpringDemo1 {
    @Test
    public void demo1(){
        UserDao userDao = new UserDaoImpl();
        UserDao userDao1 = (UserDao) new MyJdkProxy(userDao).createProxy();//通过对目标类实现动态代理方式产生一个代理类
        userDao1.save();
    }
}
//先save方法添加权限验证
//JDK动态代理
public class UserDao{
	public void save(){
		System.out.println("save.....");
	}
}
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

public class MyCglibProxy implements MethodInterceptor {
    private UserDao userDao;

    public MyCglibProxy(UserDao userDao){
        this.userDao=userDao;
    }

    public Object createProxy(){//创建代理
        //1.创建一个CGLIB的核心类
        Enhancer enhancer = new Enhancer();
        // 2.设置父类
        enhancer.setSuperclass(studentDao.getClass());
        //3.设置回调
        enhancer.setCallback(this);
        //4.生成代理
        Object proxy = enhancer.create();
        return proxy;
    }

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        if("save".equals(method.getName())){
            System.out.println("权限校验...");
            return methodProxy.invokeSuper(o,objects);
        }
        return methodProxy.invokeSuper(o,objects);
    }
}
import org.junit.Test
public class SpringDemo2{
	@Test
	public void test(){
		UserDao userDao = new UserDao();
		UserDao userDao1 = (UserDao)new MyCglibProxy(userDao) ;
		userDao1.save();
	}
}

Spring在运行期,生成动态代理对象,不需要特殊的编译器;
Spring AOP的底层就是通过JDK动态代理或CGLib动态代理技术为目标Bean执行横向织入。若目标对象实现了若干接口,Spring使用JDK的java.lang.reflect.Proxy类代理;若目标对象没有实现任何接口,Spring使用CGLIB库生成目标类的子类。
程序中应优先对接口进行创建代理,便于程序解耦维护。
标记为final的方法,不能被代理,是因为无法进行覆盖

  • JDK动态代理,是针对接口生成子类,接口中方法不能被final修饰
  • CGLib动态代理,是针对目标类产生子类,因此类或者方法不能被finak修饰
    Spring只支持方法连接点,不提供属性连接点。

猜你喜欢

转载自blog.csdn.net/Ally441/article/details/88562189