有人qq要刷 赞吗?或者会员

jethai 的BLOG
用户名:jethai
文章数:344
访问量:96056
注册日期:
阅读量:5863
阅读量:12276
阅读量:369571
阅读量:1064205
51CTO推荐博文
概念:静态代理:由程序员创建或特定工具自动生成源代码,再对其编译。在程序运行前,代理类的.class文件就已经存在了。&动态代理:在程序运行时,运用反射机制动态创建而成。 JDK的动态代理用起来非常简单,当它有一个限制,就是使用动态代理的对象必须实现一个或多个接口。如果想代理没有实现接口的继承的类,该怎么办?现在我们可以使用CGLIB包。JDK动态代理实现import&java.lang.reflect.C
import&java.lang.reflect.InvocationH
import&java.lang.reflect.InvocationTargetE
import&java.lang.reflect.M
import&java.lang.reflect.P
import&java.util.ArrayL
import&java.util.C
public&class&ProxyTest&{
&&&&static&StringBuilder&sBuilder=new&StringBuilder();
&&&&public&static&void&main(String[]&args)&throws&NoSuchMethodException,&SecurityException,&InstantiationException,&IllegalAccessException,&IllegalArgumentException,&InvocationTargetException&{
&&&&&&&&//代理类字节码
Class&clazzProxy1=&&&&Proxy.getProxyClass(Collection.class.getClassLoader(),&Collection.class);
//代理类构造方法列表,没有无参构造方法
System.out.println("...........begin&constructors&list............");
&&&&Constructor[]&constructors=&clazzProxy1.getConstructors();
&&&&&for(Constructor&constructor:constructors){
&&&&&&&&&StringBuilder&sBuilder=new&StringBuilder();
&&&&&&&&sBuilder.append(constructor.getName()).append("(");
&&&&&&&&Class[]&clazzparams&=constructor.getParameterTypes();
&&&&&&&&for(Class&clazzparam:clazzparams){
&&&&&&&&&&&&
&&&&&&&&&&&&sBuilder.append(clazzparam.getName()).append(",");
&&&&&&&&&&&&
&&&&&&&&if(clazzparams.length!=0){
&&&&&&&&&&&&
&&&&&&&&&&&&sBuilder.deleteCharAt(sBuilder.length()-1);
&&&&&&&&sBuilder.append(")");
&&&&&&&&System.out.println(&sBuilder.toString());
&&&&//代理类方法列表
&&&&System.out.println("...........begin&methods&list............");
&&&&Method[]&methods=&clazzProxy1.getMethods();
&&&&&for(Method&method:methods){
&&&&&&&&&StringBuilder&sBuilder=new&StringBuilder();
&&&&&&&&sBuilder.append(method.getName()).append("(");
&&&&&&&&Class[]&clazzparams&=method.getParameterTypes();
&&&&&&&&for(Class&clazzparam:clazzparams){
&&&&&&&&&&&&
&&&&&&&&&&&&sBuilder.append(clazzparam.getName()).append(",");
&&&&&&&&&&&&
&&&&&&&&if(clazzparams.length!=0){
&&&&&&&&&&&&
&&&&&&&&&&&&sBuilder.deleteCharAt(sBuilder.length()-1);
&&&&&&&&sBuilder.append(")");
&&&&&&&&System.out.println(&sBuilder.toString());
&&&&&//通过字节码创建代理类的实例,不能用newInstance(),构造方法传入InvocationHandler
&&&&&System.out.println("...........begin&create&instance&object............");
&&&&&&&&Constructor&constructor=clazzProxy1.getConstructor(InvocationHandler.class);
&&&&Collection&proxy1=&&&&(Collection)&constructor.newInstance(new&InvocationHandler(){
&&&&&&&&&&&&@Override
&&&&&&&&&&&&public&Object&invoke(Object&proxy,&Method&method,&Object[]&args)
&&&&&&&&&&&&&&&&&&&&throws&Throwable&{
&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&return&
&&&&&&&&&&&&}
&&&&&&&&&&&&
&&&&&&&&});
&&&&System.out.println(proxy1);
&&&&proxy1.clear();//无返回值的方法成功
&&&&//一步到位创建代理类实例
&&&&Collection&proxy2=(Collection)&Proxy.newProxyInstance(Collection.class.getClassLoader(),new&Class[]{Collection.class},&new&InvocationHandler(){
&&&&&&&&ArrayList&target=new&ArrayList&&();//被代理对象,目标对象
&&&&&&&&@Override
&&&&&&&&public&Object&invoke(Object&proxy,&Method&method,&Object[]&args)
&&&&&&&&&&&&&&&&throws&Throwable&{
&&&&&&&&&&&&
&&&&&&&&&&&&long&begintime=System.currentTimeMillis();
&&&&&&&&&&&&Object&retVal=method.invoke(target,&args);
&&&&&&&&&&&&long&endtime=System.currentTimeMillis();
&&&&&&&&&&&&System.out.println(method.getName()+"&running&time&is&"&+(endtime-begintime));
&&&&&&&&&&&&return&retV
&&&&proxy2.add("lhm");
&&&&proxy2.add("zxx");
&&&&proxy2.add("bxd");
&&&&System.out.println(proxy2.size());
&&&&System.out.println(proxy2.getClass().getName());
}CGLIB(CODE GENERLIZE LIBRARY)代理是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的所有方法,所以该类或方法不能声明称final的。spring中Aspect动态代理设置Spring提供了两种方式来生成代理对象: JDKProxy和Cglib,具体使用哪种方式生成由AopProxyFactory根据AdvisedSupport对象的配置来决定。默认的策略是如果目标类是接口,则使用JDK动态代理技术,如果目标对象没有实现接口,则默认会采用CGLIB代理。如果目标对象实现了接口,可以强制使用CGLIB实现代理(添加CGLIB库,并在spring配置中加入&aop:aspectj-autoproxy proxy-target-class="true"/&)。本文出自 “” 博客,请务必保留此出处
了这篇文章
类别:┆阅读(0)┆评论(0)Spring中JDK的动态代理和CGLIB代理的区别 - [ J2EE 企业级框架 ] - 看云
一,应用范围
1,如果目标对象实现了接口,在默认情况下会采用JDK的动态代理实现AOP
2,如果目标对象实现了接口,也可以强制使用CGLIB生成代理实现AOP
3,如果目标对象没有实现接口,必须引入CGLIB,Spring会在JDK的动态代理和CGLIB代理之间进行切换。
二,强制使用CGLIB代理
1,引入CGLIB的Jar:
2,Spring配置文件中加入强制使用CGLIB代理
&!-- 强制使用CGLIB代理 --&
&aop:aspectj-autoproxy proxy-target-class="true"/&
1, JDK的动态代理只能对实现了接口的类进行代理:
如上图,如果要为UserManagerImpl生成代理,这种关系下,可以使用JDK的动态代理,也可以强制使用CGLIB进行代理。
但是如果我去掉实现关系:
这时候就必须要使用CGLIB了。
另外,CGLIB在实现动态代理的时候,主要是为指定的类生成一个子类,例如,我要对上面的UserManagerImpl生成一个代理,会继承这个类,但是这个时候,如果我们把UserManagerImpl定义为final的,就无法被继承了,也就不能生成代理类了。所以,我们的Target object最好不要声明为final的。
页面正在加载中spring基础概念AOP与动态代理理解
作者:woonu
字体:[ ] 类型:转载 时间:
这篇文章主要为大家详细介绍了spring基础概念AOP与动态代理,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
一、代理模式
代理模式的英文叫做Proxy或Surrogate,中文都可译为”代理“,所谓代理,就是一个人或者一个机构代表另一个人或者另一个机构采取行动。在一些情况下,一个客户不想或者不能够直接引用一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
以简单模拟事务的执行过程说明各种代理区别
1.1 静态代理
由程序员创建或由特定工具自动生成源代码,再对其编译。在程序运行前,代理类的.class文件就已经存在了。
public interface PersonDao {
void savePerson();
public class PersonDaoImpl implements PersonDao {
public void savePerson() {
System.out.println("save person");
public class Transaction {
void beginTransaction(){
System.out.println("begin Transaction");
void commit(){
System.out.println("commit");
接下来编写静态代理类---实现PersonDao接口
* 静态代理类
* @author qjc
public class PersonDaoProxy implements PersonDao{
PersonDao personD
public PersonDaoProxy(PersonDao personDao, Transaction transaction) {
this.personDao = personD
this.transaction =
public void savePerson() {
this.transaction.beginTransaction();
this.personDao.savePerson();
* 测试静态代理
* @author qjc
public class TestPersonProxy {
public void testSave(){
PersonDao personDao = new PersonDaoImpl();
Transaction transaction = new Transaction();
PersonDaoProxy proxy = new PersonDaoProxy(personDao, transaction);
proxy.savePerson();
1、静态代理模式并没有做到事务的重用
2、假设dao有100个类,100个proxy,接口中有多少方法,在proxy层就得实现多少方法,有多少方法就要开启和提交多少事务
3、如果一个proxy实现了多个接口,如果其中的一个接口发生变化(添加了一个方法),那么proxy也要做相应改变
1.2 JDK动态代理
动态代理类:在程序运行时,运用反射机制动态创建而成。
JDK的动态代理必须具备四个条件:1、目标接口 2、目标类 3、拦截器 4、代理类
使用上个例子的PersonDao接口、PersonDaoImpl类及Transaction类
编写拦截器
import java.lang.reflect.InvocationH
import java.lang.reflect.M
1、目标类导入进来
2、事物导入进来
3、invoke完成:开启事务、调用目标对象的方法、事务提交
* @author qjc
public class Interceptor implements InvocationHandler {
private O // 目标类
private Tra
public Interceptor(Object target, Transaction transaction) {
this.target =
this.transaction =
* @param proxy 目标对象的代理类实例
* @param method 对应于在代理实例上调用接口方法的Method实例
* @param args 传入到代理实例上方法参数值的对象数组
* @return 方法的返回值,没有返回值是null
* @throws Throwable
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
String methodName = method.getName();
if ("savePerson".equals(methodName)
|| "deletePerson".equals(methodName)
|| "updatePerson".equals(methodName)) {
this.transaction.beginTransaction(); // 开启事务
method.invoke(target); // 调用目标方法
mit(); // 提交事务
method.invoke(target);
* 测试jdk动态代理
* @author qjc
public class TestJDKProxy {
public void testSave(){
* 1、创建一个目标对象
* 2、创建一个事务
* 3、创建一个拦截器
* 4、动态产生一个代理对象
Object target = new PersonDaoImpl();
Transaction transaction = new Transaction();
Interceptor interceptor = new Interceptor(target, transaction);
* 参数一:设置代码使用的类加载器,一般采用跟目标类相同的类加载器
* 参数二:设置代理类实现的接口,跟目标类使用相同的接口
* 参数三:设置回调对象,当代理对象的方法被调用时,会调用该参数指定对象的invoke方法
PersonDao personDao = (PersonDao) Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
interceptor);
personDao.savePerson();
1、因为利用JDKProxy生成的代理类实现了接口,所以目标类中所有的方法在代理类中都有。
2、生成的代理类的所有的方法都拦截了目标类的所有的方法。而拦截器中invoke方法的内容正好就是代理类的各个方法的组成体。
3、利用JDKProxy方式必须有接口的存在。
4、invoke方法中的三个参数可以访问目标类的被调用方法的API、被调用方法的参数、被调用方法的返回类型。
1、在拦截器中除了能调用目标对象的目标方法以外,功能是比较单一的,在这个例子中只能处理事务
2、拦截器中的invoke方法的if判断语句在真实的开发环境下是不靠谱的,因为一旦方法很多if语句需要写很多。&
1.3 CGLIB动态代理
使用上个例子的PersonDaoImpl类和Transaction类(不用接口)
编写拦截器类
import net.sf.cglib.proxy.E
import net.sf.cglib.proxy.MethodI
import net.sf.cglib.proxy.MethodP
* CGLIB代理 拦截器
* @author qjc
public class Interceptor implements MethodInterceptor {
private O // 代理的目标类
private Tra
public Interceptor(Object target, Transaction transaction) {
this.target =
this.transaction =
* 创建目标对象的代理对象
public Object createProxy() {
// 代码增强
Enhancer enhancer = new Enhancer(); // 该类用于生成代理对象
enhancer.setCallback(this); // 参数为拦截器
enhancer.setSuperclass(target.getClass());// 设置父类
return enhancer.create(); // 创建代理对象
* @param obj 目标对象代理类的实例
* @param method 代理实例上 调用父类方法的Method实例
* @param args 传入到代理实例上方法参数值的对象数组
* @param methodProxy 使用它调用父类的方法
* @throws Throwable
public Object intercept(Object obj, Method method, Object[] args,
MethodProxy methodProxy) throws Throwable {
this.transaction.beginTransaction();
method.invoke(target);
* 测试cglib动态代理
* 通过cglib产生的代理对象,代理类是目标类的子类
* @author qjc
public class TestCglibProxy {
public void testSave(){
Object target = new PersonDaoImpl();
Transaction transaction = new Transaction();
Interceptor interceptor = new Interceptor(target, transaction);
PersonDaoImpl personDaoImpl = (PersonDaoImpl) interceptor.createProxy();
personDaoImpl.savePerson();
1、CGlib是一个强大的,高性能,高质量的Code生成类库。它可以在运行期扩展Java类与实现Java接口。
2、用CGlib生成代理类是目标类的子类。
3、用CGlib生成 代理类不需要接口
4、用CGLib生成的代理类重写了父类的各个方法。
5、拦截器中的intercept方法内容正好就是代理类中的方法体&CGLIB和JDK动态代理区别:
目标类和代理类实现了共同的接口
拦截器必须实现InvocationHandler接口,而这个接口中invoke方法体的内容就是代理对象方法体的内容
目标类 是代理类的父类
拦截器必须实现MethodInterceptor接口,而接口中的intercept方法就是代理类的方法体,使用字节码增强机制创建代理对象的.
二、面向切面编程
OOP(面向对象编程):封装、继承、多态、抽象
&&&&&&& 封装,对代码进行基本的管理、模块化的管理。每个类可能都有自己的职能,出了问题就是论事找人就行了。从修改角度讲,直接修改代码可能有风险,这不是个长远之计,最自然的是从类型封装变化。但是新的类型和旧的体系之间怎么去融合,所以说需要在类与类之间建立一种血缘关系。那么这就是继承的需求,通过继承就可以发现这些类之间是有关联的,它们之间是有父子关系的。然后在继承基础之上多态起决定性的特征。所以说一般认为面向对象最核心的特征,其实是多态。前面几个都是在做铺垫的。多态才是它最核心的特征。子类中通过重写方法,代表了扩展这个层面的东西,而它能融入老的体系中能够正常工作,这是重用这个层面的东西,新的方法、旧的体系、扩展和重用。&
AOP(面向切面编程):
面向切面编程,是一种通过预编译方式运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术.&
OOP与AOP区别:
  OOP:针对业务处理过程的实体及其属性和行为进行抽象封装,以获得更加清楚的逻辑单元划分。
&  AOP:针对业务处理过程中的横切逻辑 进行提取,它所面对的是处理过程中的某个步骤或者阶段,以获得逻辑过程中各部分之间低耦合的隔离效果。这两种设计思想在目标上有着本质的差异。AOP做到了代码块的重用。&
spring AOP代理机制:
  1、若目标对象实现了若干接口,spring使用JDK的java.lang.reflect.Proxy类代理。
&&&&      优点:因为有接口,所以使系统更加松耦合
&&&     & 缺点:为每一个目标类创建接口
  2、若目标对象没有实现任何接口,spring使用CGLIB库生成目标对象的子类。
&&&     & 优点:因为代理类与目标类是继承关系,所以不需要有接口的存在。
&&&     & 缺点:因为没有使用接口,所以系统的耦合性没有使用JDK的动态代理好。
使用第一个例子的 PersonDao接口、PersonDaoImpl类和Transaction类
编写spring配置
&bean id="personDao" class="cn.qjc.aop.xml.PersonDaoImpl"&&/bean&
&bean id="transaction" class="cn.qjc.aop.xml.Transaction"&&/bean&
&aop:config&
&!-- 切入点表达式 确定目标类 --&
&aop:pointcut expression="execution(* cn.qjc.aop.xml.PersonDaoImpl.*(..))" id="perform"/&
&!-- ref指向对象就是切面 --&
&aop:aspect ref="transaction"&
&aop:before method="beginTransaction" pointcut-ref="perform"/&
&aop:after-returning method="commit" pointcut-ref="perform"/&
&/aop:aspect&
&/aop:config&
* 测试spring动态代理
* @author qjc
public class TransactionTest {
public void testSave(){
ApplicationContext context = new ClassPathXmlApplicationContext("cn/qjc/aop/xml/applicationContext.xml");
PersonDao personDao = (PersonDao) context.getBean("personDao");
personDao.savePerson();
spring AOP原理
1、当spring容器启动的时候,加载两个bean,对像个bean进行实例化
2、当spring容器对配置文件解析到&aop:config&的时候,把切入点表达式解析出来,按照切入点表达式匹配spring容器内容的bean
3、如果匹配成功,则为该bean创建代理对象
4、当客户端利用context.getBean获取一个对象时,如果该对象有代理对象,则返回代理对象,如果没有代理对象,则返回对象本身
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
您可能感兴趣的文章:
大家感兴趣的内容
12345678910
最近更新的内容
常用在线小工具内容是摘抄的,不知最初的原作者,见谅
Java 动态代理。具体有如下四步骤:
通过实现 InvocationHandler 接口创建自己的调用处理器;
通过为 Proxy 类指定 ClassLoader 对象和一组 interface 来创建动态代理类;
通过反射机制获得动态代理类的构造函数,其唯一参数类型是调用处理器接口类型;
通过构造函数创建动态代理类实例,构造时调用处理器对象作为参数被传入。
  cglib()是一个强大的,高性能,高质量的Code生成类库。它可以在运行期扩展Java类与实现Java接口。  cglib封装了asm,可以在运行期动态生成新的class。  cglib用于AOP,jdk中的proxy必须基于接口,cglib却没有这个限制。
原理区别:
java动态代理是利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。而cglib动态代理是利用asm开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。
1、如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP 2、如果目标对象实现了接口,可以强制使用CGLIB实现AOP 3、如果目标对象没有实现了接口,必须采用CGLIB库,spring会自动在JDK动态代理和CGLIB之间转换
如何强制使用CGLIB实现AOP? * 添加CGLIB库,SPRING_HOME/cglib/*.jar * 在spring配置文件中加入&aop:aspectj-autoproxy proxy-target-class="true"/&
JDK动态代理和CGLIB字节码生成的区别? * JDK动态代理只能对实现了接口的类生成代理,而不能针对类 * CGLIB是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法 & 因为是继承,所以该类或方法最好不要声明成final
阅读(...) 评论() &
版权所有,转载声明JDK动态代理和CGLIB代理的区别【转】 -
- ITeye技术网站
博客分类:
spring默认使用jdk代理jdk代理:只能代理实现了接口的类CGLIB代理:不仅可以对实现接口的类进行代理,同时也可以对类本身生成代理(主要是通过继承这个类来生成的,所以不要将要代理的类设成final)以下演示CGLIB对类的代理[java] view plaincopy//要生成代理的类
public class UserManagerImpl {
//implements UserManager {
public void addUser(String username, String password) {
//checkSecurity();
System.out.println("---------UserManagerImpl.add()--------");
//aspect类
public class SecurityHandler {
private void checkSecurity(JoinPoint joinPoint) {
for (int i=0; i&joinPoint.getArgs(). i++) {
System.out.println(joinPoint.getArgs()[i]);
System.out.println(joinPoint.getSignature().getName());
System.out.println("-------checkSecurity-------");
配置文件[xhtml] view plaincopy&!-- 强制使用CGLIB代理 --&
&aop:aspectj-autoproxy proxy-target-class="true"/&
&bean id="userManager" class="com.bjpowernode.spring.UserManagerImpl"/&
&bean id="securityHandler" class="com.bjpowernode.spring.SecurityHandler"/&
&aop:config&
&aop:aspect id="securityAspect" ref="securityHandler"&
以add开头的方法
&aop:pointcut id="addAddMethod" expression="execution(* add*(..))"/&
com.bjpowernode.spring包下所有的类所有的方法
&aop:pointcut id="addAddMethod" expression="execution(* com.bjpowernode.spring.*.*(..))"/&
&aop:pointcut id="addAddMethod" expression="execution(* com.bjpowernode.spring.*.add*(..)) || execution(* com.bjpowernode.spring.*.del*(..))"/&
&aop:before method="checkSecurity" pointcut-ref="addAddMethod"/&
&/aop:aspect&
&/aop:config&
client[java] view plaincopyBeanFactory factory = new ClassPathXmlApplicationContext("applicationContext.xml");
//UserManager userManager = (UserManager)factory.getBean("userManager");
UserManagerImpl userManager = (UserManagerImpl)factory.getBean("userManager");
浏览: 65298 次
来自: 沈阳
[align=center][size=small]&t ...
fusioncharts 图片2种方式使用java导出 - 项 ...
这个fusionchart免费的吗
thank you 希望以后多多交流
[flash=200,200][/flash]

我要回帖

更多关于 qq名片刷赞软件 的文章

 

随机推荐