JDK静态代理:
jdk的静态代理:必须有接口
代理接口(IEmployeeService)
^ ^
| |
| |
客户端(用户)------>代理类(EmployServerPoxy)<----- 委托类(真实类)(EmployIMP)
解释:
客户端(用户):表示用户要进行操作(输入信息,等待程序的处理操作)
代理接口(IEmployeeService):真实的目标实现的功能接口。
委托类(真实类)(EmployIMP):真实类对代理接口进行实现。
代理类(EmployServerPoxy):代理类也要对代理接口进行实现操作,并把之前的实现的功能引入进来(引入的之前的真实对象,因为代理类不仅要兼容之前的功能,还要进行扩充新的功能),
并对之前的功能做一个扩充增强。
实现过程:
发生异常:
expected single matching bean but found 2: employService,StaticPoxy
解释:Spring容器(xml)中有两个相同类型的bean,因为两个类同时实现同一个接口,
第一个:class="Spring_StaticPoxy_Poxy.EmployeeStaticPoxy"
第二个:class="Spring_StaticPoxy_Service.EmployeeServiceIMPL
同时实现:IEmployeeService接口,所以在Spring容器中找到两个相同的bean对象,不知到用哪个好,所以报错。
怎么解决呢:
第一种方式:
在测试类中 用代理类声明引入对象。
原来:
@Autowired//接口类型的对象
public IEmployeeService service;
修改之后:
@Autowired//代理类的对象
public EmployeeStaticPoxy service;
第二种方式:
在Spring容器(xml)里面用内部的bean对象
原来:
<!-- service对象 -->
<bean id="employService" class="Spring_StaticPoxy_Service.EmployeeServiceIMPL">
<property name="employee" ref="employeeDao"/>
</bean>
<!-- 代理对象-->
<bean id="StaticPoxy" class="Spring_StaticPoxy_Poxy.EmployeeStaticPoxy">
<property name="employeeService" ref="employService"/>
<property name="transcations" ref="transcations"/>
</bean>
修改之后:让service的bean作为poxy的内部bean,当以接口类型去找实现接口的类型bea对象时,只能找到一个,而另一个被隐藏掉了。
<!-- 代理对象-->
<bean id="StaticPoxy" class="Spring_StaticPoxy_Poxy.EmployeeStaticPoxy">
<property name="employeeService">
<!-- service -->
<bean class="Spring_StaticPoxy_Service.EmployeeServiceIMPL">
<property name="employee" ref="employeeDao"/>
</bean>
</property>
<property name="transcations" ref="transcations"/>
</bean>
我们应该选择第二种:
@Autowired//接口类型的对象
public IEmployeeService service;
因为在选择service 接口对象的时候,如果在调用Spring容器中的没有事物增强的bean对象,就无法进行事物增强的操作,若把对象最为代理类的内部bean,就有了事物增强的操作。
优点:扩展功能,无需更改原来的代码,只需要在代理类中进行自定义修改和添加。
缺点:若果有多个需要代理的类,就需要为多个不同的类创建不同的代理类对象。代码量庞大。
源码百度云盘自取:链接:https://pan.baidu.com/s/13-xzFVK4SobeCgZfmpHHig 密码:pr8t