我正在学习春天,我有以下几点
考虑以下bean定义:
<bean id="clientService" class="com.myapp.service.ClientServiceImpl" />
现在,考虑一下它被声明为一个切入点*使**clientService bean中的所有方法发生冲突的情况。
还请考虑ClientServiceImpl类实现了3个接口。
现在我知道了,使用clientService 来代理 bean,并且这个代理实现了所有的3个接口。
但是,实现这3种接口的确切原因是什么呢?
因此,在我看来,有两种代理(如果我说错了,请纠正我):
就像这样:
因此,在我看来,Spring使用的第一种代理是基于接口实现的(对吗?)
我认为在AOP中,额外的逻辑由方法拦截器的实现来表示(这是真的吗?)标准逻辑由定义在接口中的方法的实现来表示。
但是,如果前面的推理是正确的,那么我的疑问是:为什么我需要定义这些接口,并由对象包装的对象实现这些接口呢?(我无法理解代理本身是否实现了这些接口)。
为什么?到底是怎么回事?
Tnx
发布于 2015-04-15 17:11:08
但是,实现这3种接口的确切原因是什么呢?
如果代理没有实现所有这些接口,那么bean就不能连接到使用该接口的其他bean中(您将得到一个ClassCastException)。例如,将该接口的所有bean自动放入bean中。此外,如果代理没有实现接口,像getBeanNamesForType这样的东西就不能工作。
因此,在我看来,有两种代理(如果我说错了,请纠正我)。
是的没错。见ScopedProxyMode。默认情况下,Spring不会创建代理。它只在需要包装bean以添加附加行为(AOP)时才创建代理。请注意,还有一些CGLIB代理的一个特例使用Objenesis来处理没有默认构造函数的子类目标。
CGLIB代理:在wich中,在我看来,代理扩展了包装对象的实现,添加了额外的逻辑特性。
当您使用基于CGLIB的代理时,您的bean的构造函数会被调用两次:一次是实例化动态生成的子类(创建代理),另一次是创建实际bean (目标)。
我认为在AOP中,额外的逻辑由方法拦截器的实现来表示(这是真的吗?)
代理实际上只是调用需要应用的通知链。该建议不是在代理本身中实现的。例如,@Transactional
的建议位于TransactionAspectSupport中。看看JdkDynamicAopProxy的源代码。
标准逻辑由定义在接口中的方法的实现来表示。
假设您是针对接口进行编程并使用JDK代理,这是正确的。
但是,如果前面的推理是正确的,那么我的疑问是:为什么我需要定义这些接口,并由对象包装的对象实现这些接口呢?(我无法理解代理本身是否实现了这些接口)。
如果要使用基于接口的代理,则需要使用接口。只需确保所有bean都实现接口,所有建议的方法都由这些接口定义,并且当一个bean依赖于另一个bean时,依赖关系是使用接口指定的。Spring将负责构造代理并确保它实现所有接口。
在您的关系图中,您有"Spring代理(此)“。当您使用任何类型的代理时,您必须非常小心地使用this
。
this
传递给某些外部代码,则将传递AOP建议的目标。如果其他代码使用该引用,则调用将不应用AOP通知(同样,您正在绕过代理)。https://stackoverflow.com/questions/29650355
复制相似问题