一个抽象类caCu
一个实现抽象的类cacufun
一个代理类Proxi
ApplicationContext ioc=new ClassPathXmlApplicationContext("apContext.xml");
caCu test=ioc.getBean(caCu.class);
int result=test.add(3, 4);
System.out.println(test.toString()+"\n"+test.getClass());
输出结果为
cacufun [getClass()=class ProxyShows.cacufun, hashCode()=490391704, toString()=ProxyShows.cacufun@1d3ac898]
class com.sun.proxy.$Proxy18
可以看出getBean获取的test不是cacufun本身,而是代理类Proxy,但它的toString还是可以正常调用(只要是cacufun类的public方法都可以被正常调用)
若对于接口cacu在同一个包里建立超过一个的实现类并且都在这两个类头部注明@Service则会出现冲突。
No qualifying bean of type 'ProxyShows.caCu' available:
expected single matching bean but found 2: cacufun,cacufun2
由此可以总结出代理类的运行原理:通过传入的接口类A在包内寻找匹配的实现该接口A且注明@Service的类B。
代理类的原理是依据了23种设计模式的代理模式,ProxySubject引用RealSubject并为其增添各种服务。
另外,之所以用抽象类获取getBean返回的对象而不是用实现类也是因为上述代理类的运行原理导致的,即各种资料常说的:代理类只能通过接口类才能与实现类产生联系。