在Spring中、AOP的编程思想实际上跟我们之前用的过滤器或拦截器实现思路差不多;在了解AOP之前、我们先来说下代理模式吧;
代理模式:当程序不能或不想处理某个任务时,可以通过引用代理类来帮助它实行该任务。
目标对象 -- 委托人即被代理的对象
代理对象 -- 不能违背委托人的真实意愿,
代理要求:(代理对象必须跟目标对象具有相同的抽象接口)通俗讲就是不能违背目标对象的本意;所以、这里我们就要引入一个抽象接口的角色。
下面看例子:
/**
* 代理模式测试
*/
public void testProxy1()throws Exception{
//同样的、先解析spring配置文件,通过解析实例化相应对象
ApplicationContext ioc= new ClassPathXmlApplicationContext
("applicationContext.xml");
//这里一样不能实例化得到对象、要通过getBeam方法获取已实例化的对象
TestAction action = (TestAction)ioc.getBean("testAction");
try {
//然后再调用要实现的方法
action.saveObject();
action.findByName();
} catch (Exception e) {
e.printStackTrace();
}
}
在spring配置文件中、我们需要配置如下方法;
<!-- 代理类 此配置旨在表达所找的代理对象-->
<bean id="proxyDAO" class="hn.spring.why.ProxLogDAO">
<property name="baseDAO" ref="hibernateDAO"/>
</bean>
<!-- 此配置是原来的action所依赖的DAO 实现类、但现在通过上面的配置,引入到代理类中去实现了-->
<bean id="testAction" class="hn.spring.why.TestAction"
scope="prototype">
<!-- 维护当前action类依赖的DAO实现类-->
<property name="baseDAO" ref="proxyDAO"/>
</bean>
接着代理目标对象输出日志信息
public class ProxLogDAO implements IBaseDAO {
private IBaseDAO baseDAO; //代理的目标对象
//注入目标对象
public void setBaseDAO(IBaseDAO baseDAO) {
this.baseDAO = baseDAO;
}
public void saveObject(Object obj) {
System.out.println("【saveObject 日志处理 Begin............】");
baseDAO.saveObject(obj); //调用目标对象上的目标方法
System.out.println("【saveObject 日志处理 end............】");
}
public List getAllObectsByName(String name) {
System.out.println("【getAllObectsByName 日志处理 Begin............】");
List list = baseDAO.getAllObectsByName(name);
System.out.println("【getAllObectsByName 日志处理 end............】");
return list;
}
}
这样就起到了代理作用、但这中静态代理也有问题,就是它必须基于抽象接口提供的不同代理类。系统中有多少抽象接口、就需要写多少代理类;它的灵活度是不够的。所以、我们大都实际使用中大都用的是动态代理。
动态代理:基于java发射API
在javaJDK文档中、我们要熟悉的有两个类,一个Proxy、它是提供用于创建动态代理类和静态方法;即动态地创建和代理类及代理类的实例。类中创建实例的方法是newProxyInstance();这个代理类实际上不存在的、它是运行时动态产生的也就是虚拟的。但是它是关联的呢、实际上,每个代理实例都有一个关联的调用处理 程序对象,它可以实现接口InvocationHandler;而在这个接口中有一个invoke方法、只要你调用这个接口,就会实现这个方法。、
下面来看例子吧
首先我们创建一个动态代理类、让它实现接口InvocationHandler
public class DynamicProxyDAO implements InvocationHandler {
//同时内部提供invoke方法
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
在这个类中、除了提供的方法,我们需要自己提供一个方法来实现动态创建代理类
public Object createProxyInstance(){
/**
* @param loader 用于加载代理类动态实现的接口
* @param interfaces 目标对象上的所实现的接口列表(代理对象必须与目标对象具备相同的抽象接口)
* @param this 代理对象绑定的处理程序(代理对象上的方法被调用时,就会调用该接口中的invoke()
*/
return Proxy.newProxyInstance(loader ,interfaces , this);
}
在实现此方法前、我们必须给它提供一个目标对象
private Object target; //被代理的目标对象
//用set方法来注入
public void setTarget(Object target){
this.target = target;
}
然后在创建动态代理方法中、我获取目标对象的类信息
Class clazz = target.getClass();
再将返回的值变换
return Proxy.newProxyInstance(clazz.getClassLoader(),
clazz.getInterfaces(), this);
最后、同样地需要在spring配置文件中配置bean文件
<!-- 动态代理 -->
<bean id="dynamicDAO"class="hn.spring.why.DynamicProxyDAO">
<property name="target" ref="hibernateDAO"/>
</bean>
现在我们来调用动态创建代理的方法
public void testProxy2()throws Exception{
ApplicationContext ioc = new ClassPathXmlApplicationContext
("applicationContext.xml");
DynamicProxyDAO proxyDAO = (DynamicProxyDAO)ioc.getBean("dynamicDAO");
//创建代理类的实例
IBaseDAO baseDAO = (IBaseDAO)proxyDAO.createProxyInstance();
//调用代理对象上的代理方法
baseDAO.saveObject("");
}
到这里、我似乎认为基本已经可以实现了;但是测试时发现这里还有一个重要的地方没做:反射调用
在上面的invoke方法中、我们代理方法中没调用目标对象上的目标方法;
Object result = method.invoke(target, args);
这里的args为参数数组
Return result;
这样便可以通过动态代理来调用实现类中方法;这就是动态代理。
分享到:
相关推荐
死磕Spring之AOP篇 - Spring AOP两种代理对象的拦截处理(csdn)————程序
跟开涛学习SpringAop之后的一些测试代码,也是这篇帖子测试代码的补充https://my.oschina.net/longfong/blog/805410
有关于Spring,我们最常用的两个功能就是IOC和AOP,前几篇文章从源码级别介绍了Spring容器如何为我们生成bean及bean之间的依赖关系 下面我们接着来看AOP的源码实现。 有关于AOP,我们在面试中也被无数次问到...
本篇文章主要介绍了Java之Spring AOP 实现用户权限验证,用户登录、权限管理这些是必不可少的业务逻辑,具有一定的参考价值,有兴趣的可以了解一下。
Spring Aop的底层实现技术 --- Jdk动态代理原理 很不错的一篇文章
本篇文章主要介绍了详解Spring AOP 拦截器的基本实现,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
Spring AOP 学习记录 AOP(面向切面编程)方面的知识又是看了忘忘了看,今天有空记录下AOP的知识点。主要分为以下几方面: 1、AOP相关术语 2、基础知识及示例 3、增强分类 1、AOP相关术语 连接点...
这是一个jar,用来支持spring框架中的aop部分,版本是5.2.7,官网可以下到,我的前几篇博客里也有写下载网址。本来不想设置积分,但是转念一想又设置了,我觉得不设置对不起我的网。
下面小编就为大家分享一篇Spring Aop之AspectJ注解配置实现日志管理的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
本篇文章主要介绍了spring aop实现用户权限管理的示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
【框架源码篇 03】Spring源码手写篇-手写AOP
spring编程, AOP方面的.挺实用的
本篇文章主要介绍了spring aop action中验证用户登录状态的实例代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
下面小编就为大家分享一篇spring AOP自定义注解方式实现日志管理的实例讲解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
Spring Framework中的AOP编程之入门篇
Spring学习篇AOP知识整理编程开发技术共4页.pdf.zip
分布式环境下数据库的读写分离策略是解决数据库读写性能瓶颈的一个关键解决方案,这篇文章主要介绍了使用Spring AOP实现MySQL数据库读写分离案例分析(附demo),有兴趣的可以了解一下。
本篇文章主要介绍了详解使用Spring AOP和自定义注解进行参数检查,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
本篇文章主要介绍了spring boot如何使用spring AOP实现拦截器,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
采用注解模式,和XML模式对AOP面向切面编程进行测试。