spring代理对象都是代理对象吗

首页 / 新闻资讯 / 正文

         最近看到一个比较有意思的问题,springIoc 产生的对象是否都是代理对象?答案是:spring ioc默认的都是原生对象  只有通过aop增强的对象才是代理对象。有@Transactional  注解或者配置文件:

<aop:config>    <aop:pointcut id="txPointcut" expression="execution(* com..service.impl.*.*(..))" />    <aop:advisor pointcut-ref="txPointcut" advice-ref="txAdvice" /> </aop:config> 

说到代理,又分为静态代理和动态代理。

首先定义一个接口:

public interface Iuser {     void save(); } 
接口实现: 
public class UserService implements Iuser {     @Override     public void save() {         System.out.println("save user 1");     } } 
 代理类: 
public class UserServiceProxy implements Iuser{       Iuser iuser;       public UserServiceProxy(Iuser iuser) {         this.iuser = iuser;     }       @Override     public void save() {         System.out.println("save user before");         iuser.save();         System.out.println("save user after");     }   测试:     public static void main(String[] args) {         Iuser iuser = new UserService();         // 注入原生对象         UserServiceProxy userServiceProxy = new UserServiceProxy(iuser);         userServiceProxy.save();     } 输出: save user before save user 1 save user after 

   优点:

  1. 易于理解和实现

  2. 代理类和真实类的关系是编译期静态决定的,和下文马上要介绍的动态代理比较起来,执行时没有任何额外开销

缺点:

每一个真实类都需要一个创建新的代理类。

实现方式有两种,一个是JDK原生动态代理这个必须是接口,还有一种就是cglib来实现。

还有几个比较经典的面试题:

  1. 一个类里面有transaction注解,在A方法里面调研B方法事务会不起作用?

这个就因为B方法是通过this调用的,this代表的是当前的原生对象,以至于事务不起作用。

  2.为什么jdk动态代理必须基于接口 ?

     生成的代理类继承了Proxy,由于java是单继承,所以只能实现接口,通过接口实现 从代理模式的设计来说,充分利用了java的多态特性,也符合基于接口编码的规范 。

3.spring 默认是哪种代理方式?