[转] 工场模式 IOC AOP
[转] 工厂模式 IOC AOP控制反转( 通过下列代码说明如何使用Picocontainer实现AOP,该例程主要实现是记录lo
[转] 工厂模式 IOC AOP
控制反转(
通过下列代码说明如何使用Picocontainer实现AOP,该例程主要实现是记录logger功能,通过Picocontainer可以使用简单一行,使所有的应用类的记录功能激活。
首先编制一个记录接口:
java 代码
- public?interface?Logging?{ ?? ??
- public?void?enableLogging(Log?log); ?? ??
- }??
?
有一个LogSwitcher类,主要用来激活具体应用中的记录功能:
java 代码
- import?org.apache.commons.logging.Log; ?? public?class?LogSwitcher ??
- { ?? ?protected?Log?m_log; ??
- ?public?void?enableLogging(Log?log)?{ ?? m_log?=?log; ??
- m_log.info("Logging?Enabled"); ?? } ??
- }???
一般的普通应用JavaBeans都可以继承这个类,假设PicoUserManager是一个用户管理类,代码如下:
java 代码
- public?class?PicoUserManager?extends?LogSwitcher ?? {? ??
- .....?//用户管理功能 ?? } ??
- public?class?PicoXXXX1Manager?extends?LogSwitcher ?? {? ??
- ?? .....?//业务功能 ??
- } ?? public?class?PicoXXXX2Manager?extends?LogSwitcher ??
- {? ?? ??
- .....?//业务功能 ?? }??
?
注意LogSwitcher中Log实例是由外界赋予的,也就是说即将被外界注射进入,下面看看使用Picocontainer是如何注射Log的具体实例的。
java 代码
- DefaultPicoContainer?container?=?new?DefaultPicoContainer(); ?? container.registerComponentImplementation(PicoUserManager.class); ??
- container.registerComponentImplementation(PicoXXXX1Manager.class);? ?? container.registerComponentImplementation(PicoXXXX2Manager.class); ??
- .....? ?? ??
- Logging?logging?=?(Logging)?container.getComponentMulticaster(); ?? ??
- logging.enableLogging(new?SimpleLog("pico"));//激活log??
?
由上代码可见,通过使用简单一行logging.enableLogging()方法使所有的应用类的记录功能激活。这是不是类似AOP的advice实现?
总之,使用Ioc模式,可以不管将来具体实现,完全在一个抽象层次进行描述和技术架构,因此,Ioc模式可以为容器、框架之类的软件实现提供了具体的实现手段,属于架构技术中一种重要的模式应用。J道的JdonSD框架也使用了Ioc模式。
参考资料:
Inversion of Control Containers and the Dependency Injection pattern
A Brief Introduction to IoC
Ioc容器的革命性优点
Java企业系统架构选择考量
IOC模式的思考和疑问
三、IoC的几种实现类型
(1)Type1接口注入
通常做法是利用接口将调用者与实现者分离。
java 代码
- public?class?Sport?{ ?? private?InterfaceBall?ball;?//InterfaceBall是定义的接口 ??
- public?void?init()?{ ?? //Basketball实现了InterfaceBall接口 ??
- ball?=?(InterfaceBall)?Class.forName("Basketball").newInstance(); ?? } ??
- }??
Sport类在编译期依赖于InterfaceBall的实现,为了将调用者与实现者分离,我们动态生成Basketball类并通了强制类型转换为InterfaceBall。Apache Avalon是一个典型的Type1型IoC容器。
(2)setter方法注入
在类中暴露setter方法来实现依赖关系。
java 代码
- public?class?Sport?{ ?? private?InterfaceBall?ball; ??
- public?void?setBall(InterfaceBall?arg)?{ ?? ball?=?arg; ??
- } ?? }??
这种方式对已经习惯了JavaBean的程序员而言,更显直观。Spring就是实现了该类型的轻量级容器。
(3)Type3构造子注入
即通过构造方法完成依赖关系。
java 代码
- public?class?Sport?{ ?? private?InterfaceBall?ball; ??
- public?Sport(InterfaceBall?arg)?{ ?? ball?=?arg; ??
- } ?? }??
可以看到,通过类的构造方法建立依赖关系。由于Type3在构造期就形成了对象的依赖关系,即存对象的重用变的困难。有些框架需要组件提供一个默认的构造方法,此时就体现了Type3的局限性。通常所有的参数都是通过构造方法注入的,当对象间的依赖关系较多时,构造方法就显的比较复杂,不利于单元测试。PicoContainer就是实现了Type3依赖注入模式的轻量级容器。