动态代理

Java动态代理

若如初见. 提交于 2020-03-07 10:52:54
什么是动态代理 为什么要用动态代理 实战demo import java . lang . reflect . InvocationHandler ; import java . lang . reflect . Method ; import java . lang . reflect . Proxy ; public class ProxyTest { public static void main ( String [ ] args ) { UserServiceProxy userServiceProxy = new UserServiceProxy ( new UserServiceImpl ( ) ) ; UserService aaa = userServiceProxy . getInstance ( ) ; System . out . println ( aaa . getUserName ( ) ) ; System . out . println ( aaa . getUserAge ( ) ) ; } } interface UserService { String getUserName ( ) ; int getUserAge ( ) ; } class UserServiceImpl implements UserService {

Java的三种代理模式

人走茶凉 提交于 2020-03-07 10:43:11
1.代理模式 代理(Proxy)是一种设计模式,提供了对目标对象另外的访问方式;即通过代理对象访问目标对象.这样做的好处是:可以在目标对象实现的基础上,增强额外的功能操作,即扩展目标对象的功能. 这里使用到编程中的一个思想:不要随意去修改别人已经写好的代码或者方法,如果需改修改,可以通过代理的方式来扩展该方法 举个例子来说明代理的作用:假设我们想邀请一位明星,那么并不是直接连接明星,而是联系明星的经纪人,来达到同样的目的.明星就是一个目标对象,他只要负责活动中的节目,而其他琐碎的事情就交给他的代理人(经纪人)来解决.这就是代理思想在现实中的一个例子 用图表示如下: 代理模式的关键点是:代理对象与目标对象.代理对象是对目标对象的扩展,并会调用目标对象 1.1.静态代理 静态代理在使用时,需要定义接口或者父类,被代理对象与代理对象一起实现相同的接口或者是继承相同父类. 下面举个案例来解释: 模拟保存动作,定义一个保存动作的接口:IUserDao.java,然后目标对象实现这个接口的方法UserDao.java,此时如果使用静态代理方式,就需要在代理对象(UserDaoProxy.java)中也实现IUserDao接口.调用的时候通过调用代理对象的方法来调用目标对象. 需要注意的是,代理对象与目标对象要实现相同的接口,然后通过调用相同的方法来调用目标对象的方法 代码示例:静态代理 /**

java设计模式-代理模式

雨燕双飞 提交于 2020-03-07 08:00:17
代理模式是java最常见的设计模式之一。spring的aop就是使用了代理模式。 一般而言,代理模式分为静态代理和动态代理两种。 作为结构类的设计模式,作用在于不修改类内部代码的情况下,对类进行拓展,是对继承机制的一种补充。 eg :下面就用户登录这个例子实现一下代理模式。    基本需求是:实现用户的登录和修改昵称功能。 上代码,先是IUser接口和user实现类 public interface IUser { //登录 void login(String userId,String password); //修改昵称 void editNickname(String nickname); } public class User implements IUser { private String nickname; private String userId; private String password; public User(String userId,String password){ this.userId = userId; this.password = password; } @Override public void login(String userId, String password){ if(this.userId == userId && this

JDK动态代理

三世轮回 提交于 2020-03-07 08:00:03
设计模式之代理模式 通过增加代理来解耦A与C之间的调用,这样可以封装原来C调用A的一些相关细节,转换成C直接调用B中封装后的代理方法,则等同于访问A。对于WebService的远程调用时,如果我们使用添加Web引用的方式,那么WebService会为我们自动生成代理类的 所谓代理,就是代表某个真实对象,为另一个对象提供一个替身或占位符以控制对这个对象的访问。 JDK动态代理概念 运行时动态生成一个实际对象的代理,能过代理进行控制访问 与静态代理相比:    动态代理类的字节码在程序运行时由Java反射机制动态生成,无需程序员手工编写它的源代码。动态代理类不仅简化了编程工作,而且提高了软件系统的可扩展   性,因为Java 反射机制可以生成任意类型的动态代理类 JDK的动态代理是建立在接口编程上,如果一个类没有实现接口,则JDK无法生成相对应的代理类,并且只有接口中的方法能够被代理 应用:   连接池的实现,调用close方法只是放回连接池而不是并闭,这样就可以使用代理代管close方法,如果方法名是close就使用自定义处理方法   AOP的实现,在调用方法前后调用其他处理方法 JDK动态代理实现   通过 java.lang.reflect.Proxy中的newProxyInstance方法创建一个代理类 InvocationHandler 接口自定义处理逻辑 接口:

动态代理

梦想的初衷 提交于 2020-03-05 11:51:36
动态代理我个人理解是 给原对象A添加个代理对象,然后通过代理对象去操纵原对象A, 也就是中介,例如房屋中介 动态代理三个角色 真实对象(A),,代理对象,,抽象对象(接口) 特点是 更灵活,耦合性低,通过一个代理类就可以解决多个真实对象,但是因为单继承,只能来实现接口 原理是 通过反射获取到代理类的class对象,然后获取到构造器,通过构造器获取到代理类的实例 常用的retrofit内部就是通过动态代理来实现的 自己写的,凑合看吧, 哪里有不行的,欢迎指正 //抽象角色 public interface IProxy { void show(String s); } //代理角色 public class ProxySubject implements InvocationHandler{ private static final String TAG = "ProxySubject"; //持有的被代理的对象 public Object object; public void setSubject(Object obj){ object =obj; } //通过代理类 创建代理对象 public Object getInstance(){ return Proxy.newProxyInstance(object.getClass().getClassLoader(),

简单的Dubbo笔记

老子叫甜甜 提交于 2020-03-05 07:16:34
Dubbo 是一款高性能的java RPC框架; 三大核心能力: 面向接口的远程调用, 只能容错和负载均衡, 服务自动注册和发现; Dubbo官方推荐zookeeper来作为服务的注册中心; 原理是: 扫描加了@Service的类并注册到zookeeper中,注入使用Dubbo提供的@Reference注解, Dubbo支持的协议有很多种: Dubbo 协议 http 协议 rest协议等等; 注意: 被事务管理的类无法注册到zookeeper中;原因是Spring默认使用的是JDK动态代理,而这种代理产生的代理每次会不一样,所以当Dubbo在发布服务前进行包匹配时就无法完成匹配; 解决办法是: 切换Spring的动态代理,使用cglib动态代理的方式,还需要在@ Service注解中加入interfaceClass属性,指定服务的接口类型; 来源: CSDN 作者: 素颜淡笑 链接: https://blog.csdn.net/qq_45542344/article/details/104630326

AOP面试知识整理,^_^-包括spring Aop

妖精的绣舞 提交于 2020-03-04 23:50:07
讲到java企业级开发框架,就不可避免的讲到 IOC,AOP,MCV   今天面试时被问到AOP,讲的很乱,这里整理笔记,包括AOP,spring-AOP的部分知识,错误的地方请小伙伴指出来. 谈谈你对AOP的理解: AOP概念(Aspect-Oriented Programming): 即面向切面编程,与OOP(Object - Oriented Programming,面向对象编程)相辅相成,AOP的基本单元为Aspect(切面),Struts2 的拦截器设计就是基于AOP的思想。 AOP原理: 大型系统中的 通用的服务型的代码会穿插在各个业务类 ,方法中,随着系统规模的增大,会造成 大量的代码重复 ,,且与核心代码没有太多的关系。 系统中的业务可分为 核心关注点和横切关注点 , 核心关注点是业务处理的主要流程,横切关注点是与核心业务无关的通用业务。如日志权限 等,各个横切点离散的穿插与核心业务中。导致系统中的每一个模块代码都与这些业务具有很强的依赖性,当需要添加横切功能时,需要大幅修改已有的代码。 AOP即解决这个问题, 使用AOP框架,能够将这些影响多个类的通用性服务抽取出来,(即切面) ,并通过 配置的方式明确在那些位置插入这些服务, 系统运行后,AOP框架在指定的时机自动运行这些服务,从而达到核心业务逻辑和服务性逻辑分离的目的,减少了重复代码的

Spring事务失效

倖福魔咒の 提交于 2020-03-02 18:05:31
面试必备技能:JDK动态代理给Spring事务埋下的坑 一、场景分析 最近做项目遇到了一个很奇怪的问题,大致的业务场景是这样的:我们首先设定两个事务,事务parent和事务child,在Controller里边同时调用这两个方法,示例代码如下: 1、场景A: 这里其实是分别执行了两个事物,执行的结果是两个方法都可以插入数据!如下: 2、场景B: 修改上述代码如下: Propagation.REQUIRES_NEW的含义表示:如果当前存在事务,则挂起当前事务并且开启一个新事物继续执行,新事物执行完毕之后,然后在缓刑之前挂起的事务,如果当前不存在事务的话,则开启一个新事物。 执行的结果是两个方法都可以插入数据!执行结果如下: 场景A和场景B都是正常的执行,期间没有发生任何的回滚,假如child()方法中出现了异常! 3、场景C 修改child()的代码如下所示,其他代码和场景B一样: 执行结果如下,会出现异常,并且数据都没有插入进去: 疑问1:场景C中child()抛出了异常,但是parent()没有抛出异常,按道理是不是应该parent()提交成功而child()回滚? 可能有的小伙伴要说了,child()抛出了异常在parent()没有进行捕获,造成了parent()也是抛出了异常了的!所以他们两个都会回滚! 4、场景D 按照上述小伙伴的疑问这个时候,如果对parent()方法修改

Java动态代理的两种实现方法

女生的网名这么多〃 提交于 2020-03-02 08:56:41
AOP的拦截功能是由java中的动态代理来实现的。说白了,就是在目标类的基础上增加切面逻辑,生成增强的目标类(该切面逻辑或者在目标类函数执行之前,或者目标类函数执行之后,或者在目标类函数抛出异常时候执行。不同的切入时机对应不同的Interceptor的种类,如BeforeAdviseInterceptor,AfterAdviseInterceptor以及ThrowsAdviseInterceptor等)。 那么动态代理是如何实现将切面逻辑(advise)织入到目标类方法中去的呢?下面我们就来详细介绍并实现AOP中用到的两种动态代理。 AOP的源码中用到了两种动态代理来实现拦截切入功能:jdk动态代理和cglib动态代理。两种方法同时存在,各有优劣。jdk动态代理是由 Java 内部的反射机制来实现的,cglib动态代理底层则是借助asm来实现的。总的来说,反射机制在生成类的过程中比较高效,而asm在生成类之后的相关执行过程中比较高效(可以通过将asm生成的类进行缓存,这样解决asm生成类过程低效问题)。还有一点必须注意:jdk动态代理的应用前提,必须是目标类基于统一的接口。如果没有上述前提,jdk动态代理不能应用。由此可以看出,jdk动态代理有一定的局限性,cglib这种第三方类库实现的动态代理应用更加广泛,且在效率上更有优势。。 1、定义接口和实现 package com

Java代理系列-动态代理热身

妖精的绣舞 提交于 2020-03-02 08:20:32
上一章学习了Java的静态代理,但是我们主要用的是动态代理,在学习动态代理前,先熟悉一下需要的API InvocationHandler Proxy Method InvocationHandler是使用Java动态代理 必须实现(implements)的接口 ,它只有一个方法invoke 可能使用过java反射的朋友们都见过此方法,它是用来调用最终的方法的。 下面贴出Java JDK文档对此方法的详细解释 invoke Object invoke(Object proxy, Method method, Object[] args) throws Throwable 在代理实例上处理方法调用并返回结果。在与方法关联的代理实例上调用方法时,将在调用处理程序上调用此方法。 参数: proxy - 在其上调用方法的代理实例 method - 对应于在代理实例上调用的接口方法的 Method 实例。Method 对象的声明类将是在其中声明方法的接口,该接口可以是代理类赖以继承方法的代理接口的超接口。 args - 包含传入代理实例上方法调用的参数值的对象数组,如果接口方法不使用参数,则为 null。基本类型的参数被包装在适当基本包装器类(如 java.lang.Integer 或 java.lang.Boolean)的实例中。 返回: 从代理实例的方法调用返回的值