Spring动态代理(一)

AOP

  1. AOP的全程是Aspect-Oriented Programming,即面向切面编程(也成面向方向编程),它是面向对象编程(OOP)的一种补充。

  2. AOP的专业术语:
    ● Aspect(切面):在实际应用中,切面通常是指封装的用于横向插入系统功能(如事务、日志等)的类
    ● Joinpoint(连接点):在程序执行过程之中的某个阶段点,它实际上是对象的一个操作,例如方法的调用或异常的抛出。
    ● Pointcut(切入点):是指切面与程序流程的交叉点,即那些需要处理的连接点。通常在程序中,切入点指的是类或者方法名,如某个通知要应用到所有以add开头的方法中,那么所有满足这一规则的方法都是切入点。
    ● Advice(通知/增强处理):AOP框架在特定的切入点执行的增强处理,即在定义好的切入点处所要执行的程序代码。可以将其理解为切面类中的方法,它是切面的具体实现。
    ● Target Object(目标对象):是指所有被通知的对象,也称为被增强对象。如果AOP框架采用的是动态的AOP实现,那么该对象就是一个被代理的对象。
    ● Proxy(代理):将通知应用到目标对象之后,被动态创建的对象。
    ● Weaving(织入):将切面代码插入到目标对象上,从而生成代理对象的过程。

  3. 动态代理,Spring中的AOP代理可以是JDK代理,也可以是CHLIB代理。
    ● JDK动态代理
    JDK动态代理是通过java.lang.reflect.Proxy类来实现的,我们可以调用Proxy类的newProxyInstance()方法来创建代理对象。对于使用业务接口的类,Spring默认会使用JDK动态代理来实现AOP。案例:
    (1)创建一个名为chapter03的web项目,导入Spring框架所需Jar包到项目的lib目录中,并发布到类路径下。
    (2)在src目录下,创建一个com.sinven.jdk包,在该包下创建接口UserDao,并在该接口中编写添加和删除的方法,如下:

    package com.sinven.jdk
    public interface UserDao{
    	void addUser();
    	void deleteUser();
    }
    

    (3)在com.sinven.jdk包中,创建UserDao接口的实现类UserDaoImpl,分别实现接口中的方法,并在每个方法中添加一条输出语句,如下:

    package com.sinven.jdk;
    //目标类
    public class UserDaoImpl implements UserDao{
    	@Override
    	public void addUser(){
    		System.ou.println("添加用户");
    	}
    	@Override
    	public void deleteUser(){
    		System.ou.println("删除用户");
    	}
    }
    

需要注意的是,此案例中会将实现类UserDaoImpl作为目标类,对其中的方法进行增强处理
(4)在src目录下,创建一个com.sinven.aspect包,并在该包下创建切面类MyAspect,在该类中定义一个模拟权限检查的方法和一个模拟记录日志的方法,这两个方法就表示切面中的通知,如下:

	package com.sinven.aspect;
	public class MyAspect{
		public void checkPermissions(){
			System.out.println("模拟检查权限");
		}
		public void log(){
			System.out.println("模拟记录日志");
		}
	}

(5)在com.sinven.jdk包下,创建代理类JdkProxy,该类需要实现InvocationHandler接口,并编写代理方法。在代理方法中,需要通过Proxy类实现动态代理,如下:

package com.sinven.jdk;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import com.sinven.aspect.MyAspect;
/**
* 代理类
* /
public class JdkProxy implements InvocationHandler{
	//声明目标类接口
	private UserDao userDao;
	//创建代理方法
	public Object createProxy(Userdao userDao){
		this.userDao=userDao;
		//1.类加载器
		ClassLoader classLoader=JdkProxy.class.getClassLoader();
		//2.被代理对象实现的所有接口
		Class[] clazz=userDao.getClass().getInterfaces();
		//3.使用代理类,进行增强,返回的是代理后的对象
		return Proxy.newProxyInstance(classLoader, clazz, this);
	}
	/**
	*所有动态代理类的方法调用都会交由 invoke() 方法处理
	*proxy 被代理后的对象
	*method 将要被执行的方法信息(反射)
	*args 执行方法时需要的参数
	*/
	@Override
	public Object invoke(Object proxy,Method method,Object[] args) throws Throwable{
		//声明切面
		MyAspect myAspect=new MyAspect();
		//前增强
		myAspect.checkPermissions();
		//在目标类上调用方法,并传入参数
		Object obj=method.invoke(userDao,args);
		//后增强
		myAspect.log();
		return obj;
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值