spring aop 的代理工厂
package org.springframework.aop.framework
public class ProxyFactory extends ProxyCreatorSupport {
...
}
public class ProxyCreatorSupport extends AdvisedSupport {
private AopProxyFactory aopProxyFactory;
...
/**
* Create a new ProxyCreatorSupport instance.
*/
public ProxyCreatorSupport() {
this.aopProxyFactory = new DefaultAopProxyFactory();
}
...
}
public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {
@Override
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() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
return new ObjenesisCglibAopProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}
...
}
boolean java.lang.reflect.Proxy.isProxyClass(Class<?> cl) Returns true if and only if the specified class was dynamically generated to be a proxy class using the getProxyClass method or the newProxyInstance method. The reliability of this method is important for the ability to use it to make security decisions, so its implementation should not just test if the class in question extends Proxy. Parameters:
cl the class to test
Returns:
true if the class is a proxy class and false otherwise
Throws:
NullPointerException - if cl is null
JDK 示例
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.framework.ProxyFactory; public class Main {
public static void main(String[] args) { ProxyFactory factory = new ProxyFactory(new SimplePojo());
factory.addInterface(Pojo.class);
factory.addAdvice(new SomeAdvice());
Pojo pojo = (Pojo) factory.getProxy(); // this is a method call on the proxy!
pojo.foo();
}
} class SimplePojo implements Pojo { @Override
public void foo() {
// this next method invocation is a direct call on the 'this' reference
this.bar();
} @Override
public void bar() {
// some logic...
System.out.println("barrrrrrrr");
} } interface Pojo {
public void foo(); public void bar();
} class SomeAdvice implements MethodInterceptor { @Override
public Object invoke(MethodInvocation invocation) throws Throwable {
String name = invocation.getMethod().getName();
System.out.println(name + " start");
Object proceed = invocation.proceed();
System.out.println(name + " end");
return proceed;
} }
运行结果:
foo start
barrrrrrrr
foo end
通过代理才会执行advise , 自调用(self-invocation 例如 this.bar())不会执行代理的advise 。
解决方式有两种,其一:
暴露代理(不推荐使用)
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.framework.AopContext;
import org.springframework.aop.framework.ProxyFactory; public class Main {
public static void main(String[] args) { ProxyFactory factory = new ProxyFactory(new SimplePojo());
factory.addInterface(Pojo.class);
factory.addAdvice(new SomeAdvice());
factory.setExposeProxy(true);
Pojo pojo = (Pojo) factory.getProxy(); // this is a method call on the proxy!
pojo.foo();
}
} class SimplePojo implements Pojo { @Override
public void foo() {
// this works, but... gah!
((Pojo) AopContext.currentProxy()).bar();
} @Override
public void bar() {
// some logic...
System.out.println("barrrrrrrr");
} } interface Pojo {
public void foo(); public void bar();
} class SomeAdvice implements MethodInterceptor { @Override
public Object invoke(MethodInvocation invocation) throws Throwable {
String name = invocation.getMethod().getName();
System.out.println(name + " start");
Object proceed = invocation.proceed();
System.out.println(name + " end");
return proceed;
} }
运行结果:
foo start
bar start
barrrrrrrr
bar end
foo end
其二:
抽新类,避免自调用
CGLIB 示例
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.framework.ProxyFactory; public class Main {
public static void main(String[] args) { ProxyFactory factory = new ProxyFactory(new SimplePojo());
factory.addAdvice(new SomeAdvice());
SimplePojo pojo = (SimplePojo) factory.getProxy(); // this is a method call on the proxy!
pojo.foo();
}
} class SimplePojo { public void foo() {
this.bar();
} public void bar() {
// some logic...
System.out.println("barrrrrrrr");
} } class SomeAdvice implements MethodInterceptor { @Override
public Object invoke(MethodInvocation invocation) throws Throwable {
String name = invocation.getMethod().getName();
System.out.println(name + " start");
Object proceed = invocation.proceed();
System.out.println(name + " end");
return proceed;
} }
运行结果:
foo start
barrrrrrrr
foo end
暴露代理同JDK 动态代理
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.framework.AopContext;
import org.springframework.aop.framework.ProxyFactory; public class Main {
public static void main(String[] args) { ProxyFactory factory = new ProxyFactory(new SimplePojo());
factory.addAdvice(new SomeAdvice());
factory.setExposeProxy(true);
SimplePojo pojo = (SimplePojo) factory.getProxy(); // this is a method call on the proxy!
pojo.foo();
}
} class SimplePojo { public void foo() {
((SimplePojo) AopContext.currentProxy()).bar();
} public void bar() {
// some logic...
System.out.println("barrrrrrrr");
} } class SomeAdvice implements MethodInterceptor { @Override
public Object invoke(MethodInvocation invocation) throws Throwable {
String name = invocation.getMethod().getName();
System.out.println(name + " start");
Object proceed = invocation.proceed();
System.out.println(name + " end");
return proceed;
} }
运行结果:
foo start
bar start
barrrrrrrr
bar end
foo end
相关内容
Method visibility and @Transactional
When using proxies, you should apply the @Transactional annotation only to methods with public visibility. If you do annotate protected, private or package-visible methods with the @Transactional annotation, no error is raised, but the annotated method does not exhibit the configured transactional settings. Consider the use of AspectJ (see below) if you need to annotate non-public methods.
import org.aopalliance.intercept.MethodInterceptor;import org.aopalliance.intercept.MethodInvocation;import org.springframework.aop.framework.ProxyFactory;
public class Main {public static void main(String[] args) {
ProxyFactory factory = new ProxyFactory(new SimplePojo());factory.addInterface(Pojo.class);factory.addAdvice(new SomeAdvice());factory.setExposeProxy(true);Pojo pojo = (Pojo) factory.getProxy();
// this is a method call on the proxy!pojo.foo();}}
class SimplePojo implements Pojo {
@Overridepublic void foo() {// this next method invocation is a direct call on the 'this' referencethis.bar();}
@Overridepublic void bar() {// some logic...System.out.println("barrrrrrrr");}
}
interface Pojo {public void foo();
public void bar();}
class SomeAdvice implements MethodInterceptor {
@Overridepublic Object invoke(MethodInvocation invocation) throws Throwable {String name = invocation.getMethod().getName();System.out.println(name + " start");Object proceed = invocation.proceed();System.out.println(name + " end");return proceed;}
}
spring aop 的代理工厂的更多相关文章
- 死磕Spring之AOP篇 - Spring AOP自动代理(二)筛选合适的通知器
该系列文章是本人在学习 Spring 的过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring 源码分析 GitHub 地址 进行阅读. Spring 版本:5.1 ...
- 死磕Spring之AOP篇 - Spring AOP自动代理(三)创建代理对象
该系列文章是本人在学习 Spring 的过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring 源码分析 GitHub 地址 进行阅读. Spring 版本:5.1 ...
- Hibernate 延迟加载的代理模式 和 Spring AOP的代理模式
Hibernate 延迟加载的代理模式 和 Spring AOP的代理模式 主题 概念 Hibernate 延迟加载的代理模式 Spring AOP的代理模式 区别和联系 静态代理和动态代理 概念 代 ...
- 死磕Spring之AOP篇 - Spring AOP自动代理(一)入口
该系列文章是本人在学习 Spring 的过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring 源码分析 GitHub 地址 进行阅读. Spring 版本:5.1 ...
- SSM-Spring-11:Spring中使用代理工厂Bean实现aop的四种增强
------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- 说说那四种增强:前置增强,后置增强,环绕增强,异常增强 那什么是代理工厂bean呢? org.springfr ...
- Spring AOP(基于代理类的AOP实现)
#基于代理类的AOP实现:step1: 1 package com.sjl.factorybean; /**切面类*/ import org.aopalliance.intercept.MethodI ...
- 代理实现aop以及代理工厂实现增强
一.静态代理实现 1.接口(抽象主题) 2.接口的实现类(真实主题) 3.代理类(代理主题) 4.测试类: ApplicationContext context=new ClassPathXmlApp ...
- Spring AOP 动态代理 缓存
Spring AOP应用:xml配置及注解实现. 动态代理:jdk.cglib.javassist 缓存应用:高速缓存提供程序ehcache,页面缓存,session缓存 项目地址:https://g ...
- spring aop 动态代理批量调用方法实例
今天项目经理发下任务,需要测试 20 个接口,看看推送和接收数据是否正常.因为对接传输的数据是 xml 格式的字符串,所以我拿现成的数据,先生成推送过去的数据并存储到文本,以便验证数据是否正确,这时候 ...
随机推荐
- PhoenixFD插件流体模拟——UI布局【Dynamics】详解
流体动力学 本文主要讲解Dynamics折叠栏中的内容.原文地址:https://docs.chaosgroup.com/display/PHX3MAX/Liquid+Dynamics 主要内容 Ov ...
- Python下划线简介
Python中下划线的5种含义 分享一篇文章:The Meaning of Underscores in Python. 本文介绍了Python中单下划线和双下划线("dunder" ...
- Java跨平台的原理
使用Java语言编写应用程序最大的优点在于“一次编译,处处运行”,然而这并不是说所有的Java程序都具有Java跨平台的特性, 事实上,相当一部分的Java程序是不能在别的操作系统上正确运行的. Ja ...
- Linux nfs使用krb5的方式安全挂载
配置安全的网络nfs文件共享服务 由于本人是使用的rhce模拟考试环境来做的本题目,所以文中说到的实验脚本和评分脚本,以及krb5.keytab文件只有我本套环境独有,如果自己做练习可以不去使用实验脚 ...
- LeetCode Smallest Range
数据范围是3500,3500也就是说n的平方是可以接受的.这里告诉你就是有序的,也就是在提醒你可能会是一个类似于二分的算法,所以的话其实基于这两个认识的话我们就可以利用一个枚举叫二分的算法来解决这道题 ...
- 贝叶斯分类器,随机森林,梯度下载森林,神经网络相关参数的意义和data leakage
构建的每一颗树的数据都是有放回的随机抽取的(也叫bootstrap),n_estimators参数是你想设置多少颗树,还有就是在进行树的结点分裂的时候,是随机选取一个特征子集,然后找到最佳的分裂标准.
- 用python计算圆周率Π
一.要求: 1.计算到圆周率后面越多位越好. 2.用进度条显示计算的进度. 3.要求给出圆周率Π的具体计算方法和解释. 二.算法: 1.拉马努金公式: 2.高斯-勒让德公式: 设置初始值: 反复执行以 ...
- Babel 配置选项
comments 是否去掉注释,true(默认)/false.
- SQL Server数据库中的系统数据库?
SQL Server的系统数据库分为:master,model,msdb和tempdb 1.Master数据库 Master数据库记录SQL Server系统的所有系统级别信息(表sysobjects ...
- java_25 FileReader类和FileWriter类
1.FileWriter 1.1FileWriter 用于写入字符流.要写入原始字节流,请考虑使用 FileOutputStream. public class Demo { public stati ...