Spring AOP 动态代理

JDK动态处理

接口TestDao.interface

package dynamic.jdk2;public interface TestDao {
 public void save();
 public void modify();
 public void delete();}

接口实现类TestDaoImpl.java

package dynamic.jdk2;public class TestDaoImpl implements TestDao {
 @Override
 public void save() {
  System.out.println("保存");
 }
 @Override
 public void modify() {
  System.out.println("修改");
 }
 @Override
 public void delete() {
  System.out.println("删除");
 }
}

切面类MyAspect.java

package aspect;public class MyAspect {
 public void check() {
  System.out.println("模拟权限控制");
 }
 public void except() {
  System.out.println("模拟异常处理");
 }
 public void log() {
  System.out.println("模拟日志记录");
 }
 public void monitor() {
  System.out.println("性能监测");
 }}

代理类JDKDynamicProxy.java

package dynamic.jdk2;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import aspect.MyAspect;
public class JDKDynamicProxy implements InvocationHandler{
 //声明目标类接口对象(真实对象)
 private TestDao testDao;
 /*创建代理方法,建立代理对象和真实对象的代理关系,并返回代理对象**/
 public Object createProxy(TestDao testDao) {
  this.testDao=testDao;
  //类加载器
  ClassLoader cld=JDKDynamicProxy.class.getClassLoader();
  //被代理对象实现的所有接口
  Class[] clazz=testDao.getClass().getInterfaces();
  //使用代理类进行增强,返回代理后的对象
  return Proxy.newProxyInstance(cld, clazz, this);
 }
 @Override
 public Object invoke(Object proxy,Method method,Object[] args)throws Throwable{
  //创建一个切面
  MyAspect myAspect=new MyAspect();
  //前增强
  myAspect.check();
  myAspect.except();
  //在目标类上调用方法并传入参数,相当于调用testDao中的方法
  Object obj=method.invoke(testDao,args);
  //后增强
  myAspect.log();
  myAspect.monitor();
  return obj;
  
 }}

测试类JDKDynamicTest.java

package dynamic.jdk2;public class JDKDynamicTest {
   public static void main(String[] args) {
  //创建代理对象
  JDKDynamicProxy jdkProxy=new JDKDynamicProxy();
  //创建目标对象
  TestDao testDao=new TestDaoImpl();
  /**
   * 从代理对象中获取增强后的目标对象,该对象是一个被代理的对象,它会进入代理的逻辑方法invoke中
   */
  TestDao testDaoAdvice=(TestDao)jdkProxy.createProxy(testDao);
  // 执行方法
  testDaoAdvice.save();
  System.out.println("===================");
  testDaoAdvice.modify();
  System.out.println("===================");
  testDaoAdvice.delete();
 }}

运行结果
CGLIB动态代理

目标类TestDao.java

package dynamic.cglib;public class TestDao {
 public void save() {
  System.out.println("保存");
 }
 public void modify() {
  System.out.println("修改");
 }
 public void delete() {
  System.out.println("删除");
 }
}

代理类CglibDynamicProxy.java

package dynamic.cglib;
import java.lang.reflect.Method;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import aspect.MyAspect;
public class CglibDynamicProxy implements MethodInterceptor {
 /**
  * 创建代理的方法,生成CGLIB代理对象
  * target是目标对象,需要增强的对象
  * 返回目标对象的CGLIB代理对象
  */
 public Object createProxy(Object target) {
  //创建一个动态类对象,即增强类对象
  Enhancer enhancer=new Enhancer();
  //确定需要增强的类,设置其父类
  enhancer.setSuperclass(target.getClass());
  //确定代理逻辑对象为当前对象,要求当前对象实现MethodInterceptor的方法
  enhancer.setCallback(this);
  //返回创建的代理对象
  return enhancer.create();
 }
 @Override
 public Object intercept(Object proxy,Method method,Object[] args,MethodProxy methodProxy)throws Throwable{
  //创建一个切面
  MyAspect myAspect=new MyAspect();
  //前增强
  myAspect.check();
  myAspect.except();
  //目标方法执行,返回代理结果
  Object obj=methodProxy.invokeSuper(proxy, args);
  //后增强
  myAspect.log();
  myAspect.monitor();
  return obj;
 }}

测试类CglibDynamicTest.java

 package dynamic.cglib;
   public class CglibDynamicTest {
 public static void main(String[] args) {
  //创建代理对象
  CglibDynamicProxy cdp=new CglibDynamicProxy();
  //创建目标对象
  TestDao testDao=new TestDao();
  //获取增强后的目标对象
  TestDao testDaoAdvice=(TestDao)cdp.createProxy(testDao);
  //执行方法
  testDaoAdvice.save();
  System.out.println("================");
  testDaoAdvice.modify();
  System.out.println("================");
  testDaoAdvice.delete();
 }}

运行结果与上面一样

基于代理类的AOP实现

切面类MyAspect.java

package spring.proxyfactorybean;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
/**
 * 
 * @author Mis-ren
 * 切面类
 *
 */
public class MyAspect implements MethodInterceptor {
 @Override
 public Object invoke(MethodInvocation arg0)throws Throwable{
  //增强方法
  check();
  except();
  //执行目标方法
  Object obj=arg0.proceed();
  //增强方法
  log();
  monitor();
  return obj;
 }
 public void check() {
  System.out.println("模拟权限控制");
 }
 public void except() {
  System.out.println("模拟异常处理");
 }
 public void log() {
  System.out.println("模拟日志记录");
 }
 public void monitor() {
  System.out.println("性能监测");
 }
 }

配置文件applicationContext.xml

    <?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!-- 定义目标对象 -->
    <bean id="testDao" class="dynamic.jdk2.TestDaoImpl"/>
    <!-- 创建一个切面 -->
    <bean id="myAspect" class="spring.proxyfactorybean.MyAspect"/>
    <!-- 使用Spring代理工厂定义一个名为testDaoProxy的代理对象 -->
    <bean id="testDaoProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
     <!-- 指定代理实现的接口 -->
     <property name="proxyInterfaces" value="dynamic.jdk2.TestDao"/>
     <!-- 指定目标对象 -->
     <property name="target" ref="testDao"/>
     <!-- 指定切面,织入环绕通知 -->
     <property name="interceptorNames" value="myAspect"/>
     <!-- 指定代理方式,true指定CGLIB动态代理;默认为false,指定JDK动态代理 -->
     <property name="proxyTargetClass" value="true"/>
     
   

 </bean>

 </beans>

测试类ProxyFactoryBeanTest.java

package spring.proxyfactorybean;
import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;
import dynamic.jdk2.TestDao;
public class ProxyFactoryBeanTest {
 public static void main(String[] args) {
  ApplicationContext appCon=new ClassPathXmlApplicationContext
  ("/spring/proxyfactorybean/applicationContext.xml");
  //从容器中获取增强后的目标对象
  TestDao testDaoAdvice=(TestDao)appCon.getBean("testDaoProxy");
  //执行方法
  testDaoAdvice.save();
  System.out.println("================");
  testDaoAdvice.modify();
  System.out.println("================");
  testDaoAdvice.delete();
 }
}

运行结果同上​

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值