5Spring动态代理开发小结

1.为什么要有动态代理?

  1. 好处

    1.利于程序维护
    2.利于原始类功能的增强
    3.得益于JDK或者CGlib等动态代理技术使得程序扩展性很强
  2. 为什么说使得程序扩展性很强?

    静态代理运行一个增强类需要编译为.class文件,再进入到虚拟机之中运行,如果增加一个功能,就需要重新编译文件造成维护上的灾难
    动态代理会使用JDK或者CGlib等动态代理技术在JVM直接生成字节码文件也称为动态字节码文件,直接可以在虚拟机中运行,且可以在不重新编译前提下运行

2.如何开发动态代理对象

1.MethodBeforeAdvice

1.需要原始对象,被代理对象(Target)

​ 被代理对象的接口

import org.User;

public interface UserService {
//这个User只是象征性的传入个对象
public void register(User user); public Boolean login(String name, String password);
}

​ 原始对象

import org.User;

public class UserServiceImpl implements UserService {

    @Override
public void register(User user) {
System.out.println("UserServiceImpl.register");
} @Override
public Boolean login(String name, String password) {
System.out.println("UserServiceImpl.login "+name+" "+password );
return true;
}
}

2.编写额外功能,它实现MethodBeforeAdvice接口(增强类)

​ 实现MethodBeforeAdvice 的运行在目标类之前

import org.springframework.aop.MethodBeforeAdvice;

import java.lang.reflect.Method;

public class UserPoxyBefore implements MethodBeforeAdvice {
@Override
public void before(Method method, Object[] args, Object target) throws Throwable {
System.out.println("UserPoxyBefore.before"); }
}

​ 3.在配置文件定义切入点

​ 首先得实现原始类和增强类

  <bean id="UserServicePiont" class="org.Service.UserServiceImpl"/>
<bean id="UserPoxyBefore" class="org.Service.UserPoxyBefore" />

​ 再定义切入点

  • ​ pointcut表示切入的地方,而里面的expression指定切入的方法,也就是使用这个增强类的地点
  • ​ advisor指定用哪个增强类在哪个切入点
<aop:config  >
<aop:pointcut id="UserPoxyPC" expression="execution(* *(..))"/>
<aop:advisor advice-ref="UserPoxyBefore" pointcut-ref="UserPoxyPC"/>
</aop:config>

3.调用

​ 调用时的注意事项可以看这个点这个

@Test
public void test2() {
ApplicationContext context=new ClassPathXmlApplicationContext("/ApplicationContext2.XML");
UserService userService= (UserService) context.getBean("UserServicePiont");
userService.login("SY", "123456");
userService.register(new User());
}

​ 结果,可见代理类确实使用了

UserPoxyBefore.before
UserServiceImpl.login SY 123456
UserPoxyBefore.before
UserServiceImpl.register

2.MethodInterceptor(方法拦截器)

实现的MethodInterceptor可以运行在原始方法前中后

1.实现MethodInterceptor接口

在前面准备好了原始类接着直接开发增强功能就好,开发步骤和上面的一致,只不过第二步变为实现MethodInterceptor接口,如下

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation; public class Intercepter implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable { return null;
}
}

之后添加

  • invocation.proceed() 基本低效为原始方法
		Object ret=invocation.proceed();
System.out.println("Intercepter.invoke");//增强的功能

组装起来

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation; public class Intercepter implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable { Object ret=invocation.proceed();
System.out.println("Intercepter.invoke");
return ret;
}
}

2.配置文件

实现Intercepter 即可,后续配置和上面一致

<bean id= "intercepter" class="org.Service.Intercepter"/>
<aop:config >
<aop:pointcut id="UserPoxyPC" expression="execution(* *(..))"/>
<aop:advisor advice-ref="intercepter" pointcut-ref="UserPoxyPC"/>
</aop:config>

3.运行

直接运行上面的调用代码,不用改动,也体现了程序扩展性

结果

UserServiceImpl.login SY 123456
Intercepter.invoke
UserServiceImpl.register
Intercepter.invoke

4.如何让运行intercepter在原始方法的任意位置

由于invocation.proceed() 基本低效为原始方法,所以只需要把invocation.proceed() 放在不同位置即可

如调换位置

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation; public class Intercepter implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.println("Intercepter.invoke");
Object ret=invocation.proceed();
return ret;
}
}

运行结果,可以看到运行位置不同了

Intercepter.invoke
UserServiceImpl.login SY 123456
Intercepter.invoke
UserServiceImpl.register

3.对MethodBeforeAdvice的before方法参数分析

对于before有三个参数

  • ​ Method method
  • ​ Object[] args
  • ​ Object target

我们在它的接口实现设置断点

接着DEBUG 测试方法

看到method就是原始类的方法,也就是在配置文件定义的目标方法(pointcut里的expression)
args 就是原始类的方法传输的参数
target就是目标类,和JDK动态代理极其类似

接着继续DEBUG

情况和上面一样,User我没有注入数据所以为null

对于MethodInterceptor也大致相同,就不再过多分析

5Spring动态代理开发小结的更多相关文章

  1. Mybaits之Mapper动态代理开发

    Mybaits之Mapper动态代理开发 开发规范: Mapper接口开发方法只需要程序员与Mapper接口(相当于Dao接口),由Mybatis框架根据接口定义创建接口的动态代理对象,代理对象的方法 ...

  2. java框架之MyBatis(1)-入门&动态代理开发

    前言 学MyBatis的原因 1.目前最主流的持久层框架为 Hibernate 与 MyBatis,而且国内公司目前使用 Mybatis 的要比 Hibernate 要多. 2.Hibernate 学 ...

  3. MyBatis使用Mapper动态代理开发Dao层

    开发规范 Mapper接口开发方法只需要程序员编写Mapper接口(相当于Dao接口),由Mybatis框架根据接口定义创建接口的动态代理对象,代理对象的方法体同原始Dao接口实现类方法. Mappe ...

  4. Mybatis框架三:DAO层开发、Mapper动态代理开发

    这里是最基本的搭建:http://www.cnblogs.com/xuyiqing/p/8600888.html 接下来做到了简单的增删改查:http://www.cnblogs.com/xuyiqi ...

  5. MyBatis开发Dao的原始Dao开发和Mapper动态代理开发

    目录 咳咳...初学者看文字(Mapper接口开发四个规范)属实有点费劲,博主我就废了点劲做了如下图,方便理解: 原始Dao开发方式 1. 编写映射文件 3.编写Dao实现类 4.编写Dao测试 Ma ...

  6. 一张图带你看懂原始dao与SQL动态代理开发的区别-Mybatis

    //转载请注明出处:https://www.cnblogs.com/nreg/p/11156167.html 1.项目结构区别: 2.开发区别: 注:其中原始dao开发的实现类UserDaoImpl ...

  7. JavaWeb_(Mybatis框架)Mapper动态代理开发_三

    系列博文: JavaWeb_(Mybatis框架)JDBC操作数据库和Mybatis框架操作数据库区别_一 传送门 JavaWeb_(Mybatis框架)使用Mybatis对表进行增.删.改.查操作_ ...

  8. MyBatis - Mapper动态代理开发

    Mapper接口开发方法编写Mapper接口(相当于Dao接口),由Mybatis框架根据接口定义创建接口的动态代理对象. Mapper接口开发方式是基于入门程序的基础上,对 控制程序 进行分层开发, ...

  9. MyBatis 动态代理开发

    MyBatis 动态代理开发 §  Mapper.xml文件中的namespace与mapper接口的类路径相同. §  Mapper接口方法名和Mapper.xml中定义的每个statement的i ...

随机推荐

  1. java例题_12 奖金问题(暴力破解)

    1 /*12 [程序 12 计算奖金] 2 题目:企业发放的奖金根据利润提成. 3 利润I低于或等于 10 万元时,奖金可提 10%: 4 利润高于 10 万元,低于 20 万元时,低于 10 万元的 ...

  2. 使用 Android Studio 开发 widget 安卓桌面插件

    •What AppWidget 即桌面小部件,也叫桌面控件,就是能直接显示在Android系统桌面上的小程序: 这么说可能有点抽象,看图: 像这种,桌面上的天气.时钟.搜索框等等,都属于 APP Wi ...

  3. 运维干货|交换机不同VLAN之间及相同VLAN之内进行隔离

    文中所展示的内容为VLAN与VLAN之间分隔关系,如相同VLAN用户之间进行分隔,相同VLAN一组用户之间允许通信并与其它一组用户之间进行分隔,属于VLAN的高级应用范畴.本文来源于智象运维某大神的日 ...

  4. KubeEdge云边协同设计原理

    云端组件CloudCore与k8s Master的关系 从黑盒角度看,CloudCore就是k8s的一个插件,它是非侵入的来扩展k8s的一部分功能,将原来云上的节点映射到边缘端进行管理,一个Cloud ...

  5. Kafka 常见问题汇总

    Kafka 常见问题汇总 1. Kafka 如何做到高吞吐.低延迟的呢? 这里提下 Kafka 写数据的大致方式:先写操作系统的页缓存(Page Cache),然后由操作系统自行决定何时刷到磁盘. 因 ...

  6. redis实际应用-限流

    为什么要做限流 首先让我们先看一看系统架构设计中,为什么要做"限流". 旅游景点通常都会有最大的接待量,不可能无限制的放游客进入,比如故宫每天只卖八万张票,超过八万的游客,无法买票 ...

  7. CSS快速入门基础篇,让你快速上手(附带代码案例)

    1.什么是CSS 学习思路 CSS是什么 怎么去用CSS(快速上手) CSS选择器(难点也是重点) 网页美化(文字,阴影,超链接,列表,渐变等) 盒子模型 浮动 定位 网页动画(特效效果) 项目格式: ...

  8. hdu4585 STL水题

    题意:       成立少林寺,刚开始有一个大师,id是1,攻击力是10E,现在陆续来人,每个人有自己的id,和自己的攻击力,但是每一个新来的要和之前的和尚pk,他必须选择和他攻击力差值最小的那个,如 ...

  9. hdu3986 spfa + 枚举最短路上的边

    题意: 删除一条边后,求最短路中最长的那个(敌人搞破坏). 思路: 如果你是敌人你肯定删除最短路上的边,删除别的边最短路的值是不会变的,所以直接枚举最短路上的边去删除,取得最大的就行了... #inc ...

  10. hdu4768 非常规的二分

    题意:       n个社团给同学发传单,同学一共有1--2^31这么多,每个社团有三个数A ,B ,C ,只有 满足 A ,A + C ,A + C + C ...A + KC <= B 的学 ...