Spring的AOP的底层实现

1.AOP  (面向切面编程)OOP的扩展和延伸

AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

可以进行权限校验,日志记录,性能监控,事务控制。

2.Spring底层的AOP实现原理——动态代理

      (1)JDK动态代理

只能对实现了接口的类产生代理

public interface UserDao {
	public void save();
	public void update();
	public void find();
	public void delete();
}
public class UserDaoImpl implements UserDao {

	@Override
	public void save() {
		System.out.println("保存用户....");
	}

	@Override
	public void update() {
		System.out.println("修改用户....");
	}

	@Override
	public void find() {
		System.out.println("查询用户....");
	}

	@Override
	public void delete() {
		System.out.println("删除用户....");
	}

}
package com.acat.spring.demo1;

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

/**
 * 使用JDK动态代理对UserDao产生代理
 * @author Administrator
 *
 */
public class JdkProxy implements InvocationHandler{
	//将增强的对象传递到代理中
	private UserDao userDao;
	public JdkProxy(UserDao userDao){
		this.userDao = userDao;
	}
	/**
	 * 产生UserDao的代理方法
	 */
	public UserDao createProxy(){
		
		UserDao userDaoProxy = (UserDao) Proxy.newProxyInstance(userDao.getClass().getClassLoader(), userDao.getClass().getInterfaces(), this);
		return userDaoProxy;
	}
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		//判断方法名是不是save
		if("save".equals(method.getName())){
			//增强
			System.out.println("权限校验+++++");
			return method.invoke(userDao, args);
		}
		return method.invoke(userDao, args);
	}
}
package com.acat.spring.demo1;

import org.junit.Test;

public class SpringDemo1 {
	@Test
	//jdk动态代理
	public void demo1(){
		UserDao userDao = new UserDaoImpl();
		//创建代理
		UserDao proxy = new JdkProxy(userDao).createProxy();
		proxy.save();
		proxy.update();
		proxy.find();
		proxy.delete();
	}
}

    (2)Cglib动态代理(类似于Javasisst第三方代理技术)

对没有实现接口的类产生代理对象,生成子类对象

Cglib:第三方开源代码生成类库,动态添加类的属性和方法

package com.acat.spring.demo2;

public class CustomerDao {
	
	public void save(){
		System.out.println("保存用户...");
	}
	public void update(){
		System.out.println("修改用户...");
	}
	public void find(){
		System.out.println("查找用户...");
	}
	public void delete(){
		System.out.println("删除 用户...");
	}
}
package com.acat.spring.demo2;

import java.lang.reflect.Method;

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

/**
 * Cglib动态代理
 * @author Administrator
 *
 */
public class CglibProxy implements MethodInterceptor{
	
	private CustomerDao customerDao;
	public CglibProxy(CustomerDao customerDao){
		this.customerDao = customerDao;
	}
	/**
	 * 使用Cglib产生代理的方法
	 */
	public CustomerDao createProxy(){
		//创建Cglib的核心类对象
		Enhancer enhancer = new Enhancer();
		//2.设置父类
		enhancer.setSuperclass(customerDao.getClass());
		//3.设置回调(类似于InvoicationHandler对象)
		enhancer.setCallback(this);
		//4.创建代理对象
		CustomerDao proxy = (CustomerDao) enhancer.create();
		return proxy;
	}
	@Override
	public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
		//判断方法是否为save
		if("save".equals(method.getName())){
			//增强
			System.out.println("权限校验");
			return methodProxy.invokeSuper(proxy, args);
		}
		return methodProxy.invokeSuper(proxy, args);
	}
	
}
package com.acat.spring.demo2;

import org.junit.Test;

import sun.font.CreatedFontTracker;

public class SpringDemo2 {
	@Test
	/**
	 * Cglib的测试
	 */
	public void demo1(){
		CustomerDao customerDao = new CustomerDao();
		
		CustomerDao proxy = new CglibProxy(customerDao).createProxy();
		proxy.save();
		proxy.find();
		proxy.update();
		proxy.delete();
	}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值