一、静态代理实现

  1.接口(抽象主题)

  

  2.接口的实现类(真实主题)

  

  3.代理类(代理主题)

  

  4.测试类:

     ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
ProxySubject proxySubject =(ProxySubject) context.getBean("proxySubject");
proxySubject.doSome();

二、JDK动态代理

  JDK动态代理所用到的代理类在程序调用到代理类对象时才由JVM真正创建,JVM根据传进来的 业务实现类对象 以及 方法名 ,动态地创建了一个代理类的class文件并被字节码引擎执行,然后通过该代理类对象进行方法调用。

  1.抽象主题,真实主题与上面一致

  2.动态代理类

 
package com.cmy.handler;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy; public class DoSomeBeanFactory implements InvocationHandler {
private Object target;//这其实业务实现类对象,用来调用具体的业务方法 public Object bind(Object target) {
this.target = target; //接收业务实现类对象参数 //通过反射机制,创建一个代理类对象实例并返回。用户进行方法调用时使用
//创建代理对象时,需要传递该业务类的类加载器(用来获取业务实现类的元数据,在包装方法是调用真正的业务方法)、接口、handler实现类
return Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(), this);
} @Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("前置=====");
//调用真正的业务方法
Object result = method.invoke(target, args);
System.out.println("后置=====");
return result;
}
}
 

  3.测试类

 
public class ProxyDemo {
public static void main(String[] args) {
//创建业务类对象
Subject subject=new ReallySubject();
//创建代理对象
DoSomeBeanFactory factory=new DoSomeBeanFactory();
//调用bind方法获取代理对象
Subject proxy = (Subject)factory.bind(subject);
//调用目标函数
proxy.say();
}
}
 

三、Cglib动态代理

   cglib是针对类来实现代理的,原理是对指定的业务类生成一个子类,并覆盖其中业务方法实现代理。因为采用的是继承,所以不能对final修饰的类进行代理。

  新建代理类

package com.cmy.handler;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method; public class DoSomeBeanCGlib implements MethodInterceptor{
private Object target;//业务类对象,供代理方法中进行真正的业务方法调用 //相当于JDK动态代理中的绑定
public Object getInstance(Object target) {
this.target = target; //给业务对象赋值
Enhancer enhancer = new Enhancer(); //创建加强器,用来创建动态代理类
enhancer.setSuperclass(this.target.getClass()); //为加强器指 //设置回调:对于代理类上所有方法的调用,都会调用CallBack,而Callback则需要实 现intercept()方法进行拦
enhancer.setCallback(this);
// 创建动态代理类对象并返回
return enhancer.create();
} @Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("预处理——————");
methodProxy.invokeSuper(o, objects); //调用业务类(父类中)的方法
System.out.println("调用后操作——————");
return null;
}
}
 

 四.代理工厂增强

 借助Spring IOC的机制,为ProxyFactory代理工厂的属性实现依赖注入,这样做的优点是可配置型高,易用性好。

1.创建抽象主题

public interface ProService {
public void doSome();
}

2.创建真实主题

 
public class ProServiceImpl implements  ProService {
@Override
public void doSome() {
System.out.println("123");
}
}
 

3.创建增强类

  这里实现了前置增强的接口,用前置增强来模拟增强

 
import org.springframework.aop.MethodBeforeAdvice;

import java.lang.reflect.Method;

public class BeaforeProxy implements MethodBeforeAdvice {
@Override
public void before(Method method, Object[] objects, Object o) throws Throwable {
System.out.println("前置");
}
}
 

4.配置大配置文件

 
 <!--注入bean-->
<bean id="proService" class="cn.spring.proxyFactory.ProServiceImpl"></bean>
<!--切面-->
<bean id="beaforeProxy" class="cn.spring.proxyFactory.BeaforeProxy"></bean>
<!--代理工厂实现增强-->
<bean id="ProFactory" class="org.springframework.aop.framework.ProxyFactoryBean">
<!--将增强和业务织入到一起-->
<property name="target" ref="proService"></property>
<!--拦截增强类-->
<property name="interceptorNames" value="beaforeProxy"></property>
</bean>
 

5.测试

 public static void main(String[] args) {
ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
ProService proService =(ProService) context.getBean("ProFactory");
proService.doSome();
}

6.结果

  值得注意的是这种代理工场的代理方式默认为Jdk,如果不存在接口,则使用Cglib代理,这个可以通过断点直观看出,若想规定使用,则可以在大配置文件代理工厂的节点下中设置

<!--更换代理方式   默认值为false  jdk动态代理,当没有接口时,自动改成cglib-->
<property name="proxyTargetClass" value="true"></property>

 

代理实现aop以及代理工厂实现增强的更多相关文章

  1. Spring-构造注入&注解注入&代理模式&AOP

    1.   课程介绍 1.  依赖注入;(掌握) 2.  XML自动注入;(掌握) 3.  全注解配置;(掌握) 4.  代理模式;(掌握) 5.  AOP;(掌握) 依赖注入;(掌握) 2.1.  构 ...

  2. Spring——代理工厂实现增强

    借助Spring IOC的机制,为ProxyFactory代理工厂的属性实现依赖注入,这样做的优点是可配置型高,易用性好. 1.创建抽象主题 public interface ProService { ...

  3. spring aop 的代理工厂

    参考 https://docs.spring.io/spring/docs/4.3.11.RELEASE/spring-framework-reference/htmlsingle/#aop-unde ...

  4. AOP动态代理解析4-代理的创建

    做完了增强器的获取后就可以进行代理的创建了 AnnotationAwareAspectJAutoProxyCreator->postProcessAfterInitialization-> ...

  5. Spring AOP详解 、 JDK动态代理、CGLib动态代理

    AOP是Aspect Oriented Programing的简称,面向切面编程.AOP适合于那些具有横切逻辑的应用:如性能监测,访问控制,事务管理以及日志记录.AOP将这些分散在各个业务逻辑中的代码 ...

  6. 【转载】Spring AOP详解 、 JDK动态代理、CGLib动态代理

    Spring AOP详解 . JDK动态代理.CGLib动态代理  原文地址:https://www.cnblogs.com/kukudelaomao/p/5897893.html AOP是Aspec ...

  7. Spring AOP(基于代理类的AOP实现)

    #基于代理类的AOP实现:step1: 1 package com.sjl.factorybean; /**切面类*/ import org.aopalliance.intercept.MethodI ...

  8. Java 动态代理及AOP实现机制

    AOP实现机制http://www.iteye.com/topic/1116696 AOP: (Aspect Oriented Programming) 面向切面编程AOP包括切面(aspect).通 ...

  9. Java-JDK动态代理(AOP)使用及实现原理分析

    Java-JDK动态代理(AOP)使用及实现原理分析 第一章:代理的介绍 介绍:我们需要掌握的程度 动态代理(理解) 基于反射机制 掌握的程度: 1.什么是动态代理? 2.动态代理能够做什么? 后面我 ...

随机推荐

  1. 洛谷 P1843 奶牛晒衣服(二分答案)

    嗯... 题目链接:https://www.luogu.com.cn/problem/P1843 我们二分枚举时间,看看那些衣服在蒸发后还要用烘干机,则用cnt记录它的时间. 注意w数组在操作中不能变 ...

  2. Plastic Bottle Manufacturer Tips - Attention To Plastic Bottle Processing Technology

    In fact, the processing technology of plastic bottles is actually quite strict. In fact, regular man ...

  3. Fizz Buzz in tensorflow

    code from keras.layers.normalization import BatchNormalization from keras.models import Sequential f ...

  4. 任意值运动框架Move模块 js

    function getStyle(obj, name) { if (obj.currentStyle) { return obj.currentStyle[name]; } else { retur ...

  5. 【PAT甲级】1056 Mice and Rice (25 分)

    题意: 输入两个正整数N和M(<=1000),接着输入两行,每行N个数,第一行为每只老鼠的重量,第二行为每只老鼠出战的顺序.输出它们的名次.(按照出战顺序每M只老鼠分为一组,剩余不足M只为一组, ...

  6. 第一节:Vuejs入门之各种指令

    一. 简介 Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架.与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用.Vue 的核心库只关注视图层,不仅易于上 ...

  7. 解决方法:Could not load file or assembly 'WebGrease, Version=1.5.1.25624, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies.

    最近使用VS2015调试ASP.NET 程序遇到了该问题: 在网上找了很多方法都不能解决,最后自己解决了,方法如下: 在project -> NuGet管理中找到已安装的所有程序:将Web Op ...

  8. 2.1 MySQL基础使用

    本文是课上资料的总结非原创没有转载地址 目录 引言 为什么需要数据库? 数据库和应用程序的关系 MySQL基础使用 一.数据库简介 1.1 简介 1.2 常见数据库管理系统 1.3 MySQL卸载 1 ...

  9. IP地址规划

    IP地址(Internet Protocol Address),缩写为IP Adress,是一种在Internet上的给主机统一编址的地址格式,也称为网络协议(IP协议)地址.它为互联网上的每一个网络 ...

  10. 时间和日期-<Date和SimpleDateFormat>

    第一步.定义一个Date //获取当前时间 Date now=new Date(); 第二步.定义一个SimpleDateFormat //规范时间格式 SimpleDateFormat date=n ...