`
234390216
  • 浏览: 10193795 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
博客专栏
A5ee55b9-a463-3d09-9c78-0c0cf33198cd
Oracle基础
浏览量:460810
Ad26f909-6440-35a9-b4e9-9aea825bd38e
springMVC介绍
浏览量:1771834
Ce363057-ae4d-3ee1-bb46-e7b51a722a4b
Mybatis简介
浏览量:1395454
Bdeb91ad-cf8a-3fe9-942a-3710073b4000
Spring整合JMS
浏览量:393903
5cbbde67-7cd5-313c-95c2-4185389601e7
Ehcache简介
浏览量:678229
Cc1c0708-ccc2-3d20-ba47-d40e04440682
Cas简介
浏览量:529303
51592fc3-854c-34f4-9eff-cb82d993ab3a
Spring Securi...
浏览量:1178748
23e1c30e-ef8c-3702-aa3c-e83277ffca91
Spring基础知识
浏览量:461938
4af1c81c-eb9d-365f-b759-07685a32156e
Spring Aop介绍
浏览量:150152
2f926891-9e7a-3ce2-a074-3acb2aaf2584
JAXB简介
浏览量:66868
社区版块
存档分类
最新评论

Spring Aop(十一)——编程式的创建Aop代理之ProxyFactory

阅读更多

编程式的创建Aop代理之ProxyFactory

Spring Aop是基于代理的,ProxyFactory是Spring Aop内部用来创建Proxy对象的一个工厂类。如果我们需要在程序运行时来动态的应用Spring Aop,则我们可以考虑使用ProxyFactory。使用ProxyFactory时,我们需要为它指定我们需要代理的目标对象、代理时我们需要使用的Advisor或Advice。如下示例就是一个简单的使用ProxyFactory创建MyService对象的代理,同时对其应用了一个MethodBeforeAdvice,即每次调用代理对象的方法时都将先调用MethodBeforeAdvice的before方法。

	@Test
	public void testProxyFactory() {
		MyService myService = new MyService();
		ProxyFactory proxyFactory = new ProxyFactory(myService);
		proxyFactory.addAdvice(new MethodBeforeAdvice() {

			@Override
			public void before(Method method, Object[] args,
                            Object target) throws Throwable {
				System.out.println("执行目标方法调用之前的逻辑");
				//不需要手动去调用目标方法,
                                //Spring内置逻辑里面会调用目标方法
			}
			
		});;
		MyService proxy = (MyService) proxyFactory.getProxy();
		proxy.add();
	}

指定被代理对象

ProxyFactory有多个重载的构造函数,上面示例中笔者用的是指定被代理对象的构造函数,如果我们应用的是其它构造函数,则可以通过ProxyFactory的setTarget(Object)方法来指定被代理对象。如果我们没有指定被代理对象的Class,那么默认创建出来的代理对象是我们传递的被代理对象的类型,即获取的是targetObject.getClass()类型。如果我们的被代理对象的类型是包含多个接口实现或父类型的,而我们只希望代理其中的某一个类型时,我们可以通过ProxyFactory的setTargetClass(Class)来指定创建的代理对象是基于哪个Class的。默认情况下,ProxyFactory会根据实际情况选择创建的代理对象是基于JDK代理的还是基于CBLIB代理的,即目标对象拥有接口实现且没有设置proxyTargetClass="true"或者指定的targetClass是一个接口的时候将采用JDK代理,否则将采用CGLIB代理。也就是说即算是你通过ProxyFactory.setProxyTargetClass(true)指定了将会建立基于Class的CGLIB代理,最终也不一定是CGLIB代理,因为这种情况下如果targetClass是一个接口也将建立JDK代理。这块的逻辑是由DefaultAopProxyFactory的createAopProxy()方法实现的,其源码如下。

	public AopProxy createAopProxy(AdvisedSupport config) 
            throws AopConfigException {
		if (config.isOptimize() || config.isProxyTargetClass()
                     || hasNoUserSuppliedProxyInterfaces(config)) {
			Class<?> targetClass = config.getTargetClass();
			if (targetClass == null) {
				

throw new AopConfigException("TargetSource cannot determine target class: " +
	"Either an interface or a target is required for proxy creation.");
			}
			if (targetClass.isInterface()) {
				return new JdkDynamicAopProxy(config);
			}
			return new ObjenesisCglibAopProxy(config);
		}
		else {
			return new JdkDynamicAopProxy(config);
		}
	}

ProxyFactory底层在创建代理对象的时候实际上是会委托给AopProxyFactory对象的,AopProxyFactory是一个接口,其只定义了一个createAopProxy()方法,Spring提供了一个默认实现,DefaultAopProxyFactory。ProxyFactory中使用的就是DefaultAopProxyFactory,有兴趣的朋友可以参考一下ProxyFactory的源代码。

指定Advisor

使用Aop时我们是需要对拦截的方法做一些处理的,对于Spring Aop来讲,需要对哪些方法调用做什么样的处理是通过Advisor来定义的,通常是一个PointcutAdvisor。PointcutAdvisor接口中包含主要有两个接口方法,一个用来获取Pointcut,一个用来获取Advice对象,它俩的组合就构成了需要在哪个Pointcut应用哪个Advice。所以有需要的时候我们也可以实现自己的Advisor实现。

/**
 * 简单的实现自己的PointcutAdvisor
 * @author Elim 2017年5月9日
 */
public class MyAdvisor implements PointcutAdvisor {

	@Override
	public Advice getAdvice() {
		return new MethodBeforeAdvice() {

			@Override
			public void before(Method method, Object[] args, 
  
                            Object target) throws Throwable {
				

System.out.println("BeforeAdvice实现,在目标方法被调用前调用,目标方法是:" 

+ method.getDeclaringClass().getName() + "."
						+ method.getName());
			}
		};
	}

	@Override
	public boolean isPerInstance() {
		return true;
	}

	@Override
	public Pointcut getPointcut() {
		//匹配所有的方法调用
		return Pointcut.TRUE;
	}

}
	@Test
	public void testProxyFactory2() {
		MyService myService = new MyService();
		ProxyFactory proxyFactory = new ProxyFactory(myService);
		proxyFactory.addAdvisor(new MyAdvisor());
		MyService proxy = (MyService) proxyFactory.getProxy();
		proxy.add();
	}

上述示例就是一个指定代理对象对应的Advisor的示例。其实一个代理对象可以同时绑定多个Advisor对象,ProxyFactory的addAdvisor()方法可多次被调用,且该方法还有一些重载的方法定义,可以参数Spring的API文档。

指定Advice

我们的第一个示例指定的代理对象绑定的是一个Advice,而第二个示例指定的Advisor,对此你会不会有什么疑问呢?依据我们对Spring Aop的了解,Spring的Aop代理对象绑定的就一定是一个Advisor,而且通常是一个PointcutAdvisor,通过它我们可以知道我们的Advice究竟是要应用到哪个Pointcut(哪个方法调用)?当我们通过ProxyFactory在创建代理对象时绑定的是一个Advice对象时,实际上ProxyFactory内部还是为我们转换为了一个Advisor对象的,只是该Advisor对象对应的Pointcut是一个匹配所有方法调用的Pointcut实例。

指定是否需要发布代理对象

在调用Aop代理对象的方法时,默认情况下我们是不能访问到当前的代理对象的,如果我们指定了创建的代理对象需要对外发布代理对象,那么在调用代理对象的方法时Spring会把当前的代理对象存入AopContext中,我们就可以在目标对象的方法中通过AopContext中获取到当前的代理对象了。这是通过exposeProxy属性来指定的,如果我们希望对外发布代理对象,我们可以通过exposeProxy的set方法来指定该属性的值为true。如:

	@Test
	public void testProxyFactory2() {
		MyService myService = new MyService();
		ProxyFactory proxyFactory = new ProxyFactory(myService);
		proxyFactory.setExposeProxy(true);//指定对外发布代理对象,即在目标对象方法中可以通过AopContext.currentProxy()访问当前代理对象。
		proxyFactory.addAdvisor(new MyAdvisor());
		proxyFactory.addAdvisor(new MyAdvisor());//多次指定Advisor将同时应用多个Advisor
		MyService proxy = (MyService) proxyFactory.getProxy();
		proxy.add();
	}

除了上述配置信息以外,ProxyFactory其实还可以配置很多其它的信息,更多的配置信息项请参考ProxyFactory的源代码或参考Spring API文档。

参考文档

  • Spring4.1.0官方文档
  • Spring源代码

(本文是基于Spring4.1.0所写,Elim写于2017年5月9日)

0
0
分享到:
评论

相关推荐

    aop的详细总结(包含例子)

    一、AOP 概念 二、AOP 种类 三、Spring AOP 代理原理 四、Spring AOP 通知类型 五、Spring AOP Pointcut 六、Spring AOP 中的Advisor其实就是Aspect 七、AOP ProxyFactory 八、自动代理

    Spring AOP 自动代理源码 DefaultAdvisorAutoProxyCreator

    Spring AOP源码01:Jdk动态代理底层源码 Spring AOP源码02:ProxyFactory Spring AOP源码03:JdkDynamicAopProxy Spring AOP源码04:MethodInvocation 拦截器调用 Spring AOP源码05:DefaultAdvisorAutoProxyCreator...

    spring-aop-ProxyFactoryBean 源码分析

    NULL 博文链接:https://wangxinchun.iteye.com/blog/2079585

    AOP 和 Aspect 注解切入 测试 Demo

    基于 MethodBeforeAdvice、AfterReturningAdvice 利用 Spring Api 定义前、后置处理方法,并通过代理工厂类获取代理对象(代码或Xml配置实现) 2.ProxyFactoryBean 显式地设置 Advisors、Advice、Target等(基于代理...

    Spring 2.0 开发参考手册

    7.7. 使用ProxyFactory通过编程创建AOP代理 7.8. 操作被通知对象 7.9. 使用“自动代理(autoproxy)”功能 7.9.1. 自动代理bean定义 7.9.2. 使用元数据驱动的自动代理 7.10. 使用TargetSources 7.10.1. 热交换...

    Spring-Reference_zh_CN(Spring中文参考手册)

    7.7. 使用ProxyFactory通过编程创建AOP代理 7.8. 操作被通知对象 7.9. 使用“自动代理(autoproxy)”功能 7.9.1. 自动代理bean定义 7.9.1.1. BeanNameAutoProxyCreator 7.9.1.2. DefaultAdvisorAutoProxyCreator ...

    spring.net中文手册在线版

    12.6.使用ProxyFactory类以编程方式创建AOP代理 12.7.管理目标对象 12.8.使用“自动代理”功能 12.8.1.自动代理对象的定义 12.8.1.1.ObjectNameAutoProxyCreator 12.8.1.2.DefaultAdvisorAutoProxyCreator 12.8.1.3....

    spring chm文档

    7.7. 使用ProxyFactory通过编程创建AOP代理 7.8. 操作被通知对象 7.9. 使用“自动代理(autoproxy)”功能 7.9.1. 自动代理bean定义 7.9.2. 使用元数据驱动的自动代理 7.10. 使用TargetSources 7.10.1. 热交换...

    Spring中文帮助文档

    7.7. 使用ProxyFactory通过编程创建AOP代理 7.8. 操作被通知对象 7.9. 使用“自动代理(autoproxy)”功能 7.9.1. 自动代理bean定义 7.9.2. 使用元数据驱动的自动代理 7.10. 使用TargetSource 7.10.1. 热交换...

    Spring API

    7.7. 使用ProxyFactory通过编程创建AOP代理 7.8. 操作被通知对象 7.9. 使用“自动代理(autoproxy)”功能 7.9.1. 自动代理bean定义 7.9.2. 使用元数据驱动的自动代理 7.10. 使用TargetSource 7.10.1. 热交换...

    Java Web程序设计教程

    12.4springaop的代理工厂 253 12.4.1选择合适的代理 253 12.4.2proxyfactory 254 12.4.3proxyfactorybean 254 12.5项目实战——输出日志 256 本章小结 258 课后练习 259 第13章 spring与javaee持久化数据...

    AOP实现计算器代码.zip

    使用ProxyFactory或ProxyFactoryBean实现计算器功能,同时(1)日志功能:在程序执行期间追踪正在发生的活动(打印出调用的方法,以及参数的参数值);(2)验证功能:希望计算器只能处理正数的运算,当有负数参与...

    tyloo:分布式交易框架——TCC

    基于Dubbo的ProxyFactory代理机制为服务接口生成代理对象。 基于Mysql,Redis乐观锁进行事务版本控制以及基于石英进行事务恢复。 支持各种事务日志序列化以及事务存储实现。 调用方式(版本):Dubbo,HTTP 业务场景...

    first Spring test

    1.实现特定功能的方面代码在aop中又称为“通知(Advice)”包含 前置通知 后置通知 环绕...2.spring 采用代理的方式将通知织入到原bean中,将原bean和通知都封装到--org.springframework.aop.framework.ProxyFactory.

    spring-framework-reference-4.1.2

    3. New Features and Enhancements in Spring Framework 4.0 ............................................ 17 3.1. Improved Getting Started Experience .........................................................

    SPRING API 2.0.CHM

    All Classes ...AopContext AopInvocationException AopNamespaceHandler AopNamespaceUtils AopProxy AopProxyFactory AopProxyUtils AopUtils ApplicationContext ApplicationContextAware ...

    spring-framework-reference4.1.4

    3. New Features and Enhancements in Spring Framework 4.0 ............................................ 17 3.1. Improved Getting Started Experience .........................................................

    mobileSenderDemo

    Spring Data Jpa应用程序API API1.1。 기본API가인터페이스상속하여사용 반스않고스스스스스스함함함... AOP倒影기술을활용함 ProxyFactory,反射,MethodInterceptor,JdkDynamicAopProxy,CGLib Spring数据Jpa소스를

Global site tag (gtag.js) - Google Analytics