最近在学习Struts2源码的时候,学到了Struts2的IOC功能。为了加深印象,决定写个博客。
Struts2框架中有一个容器(Container),我们先来看下它的源代码:
1 public interface Container extends Serializable { 2 3 /** 4 * 设置默认的对象获取标识 5 */ 6 String DEFAULT_NAME = "default"; 7 8 /** 9 * 进行对象的依赖注入操作。o为被注入对象的对象。 10 */ 11 void inject(Object o); 12 13 /** 14 *创建一个类的实例并进行对象的依赖注入操作。15 */ 16 <T> T inject(Class<T> implementation); 17 18 /** 19 * 根据type和name获取容器中的对象实例。 20 * 21 */ 22 <T> T getInstance(Class<T> type, String name); 23 24 /** 25 * 根据type和默认的name(type)来获取容器中的对象实例。26 * 27 */ 28 <T> T getInstance(Class<T> type); 29 30 /** 31 * 根据type获取与这个type所对应的容器中的所有注册过的name。 32 * @param type The instance type 33 * @return A set of registered names or empty set if no instances are registered for that type 34 */ 35 Set<String> getInstanceNames(Class<?> type); 36 37 /** 38 * 设置当前线程的作用范围的策略。 39 */ 40 void setScopeStrategy(Scope.Strategy scopeStrategy); 41 42 /** 43 * 删除当前线程的作用范围的策略。 44 */ 45 void removeScopeStrategy(); 46 }
从Container的源代码可以看出,容器的作用有以下三点:
①,获取对象实例。
②,对象的依赖注入。
③,处理对象的作用范围策略。
其中最重要的是第一点和第二点。那么,我们可以通过Container来获取对象的实例,具体来说,哪些实例我们可以获取到呢?
其实我们获取的是xml配置文件中的bean节点的对象和constant节点的参数。
我们来看官方文档对bean节点的解释:
从官方的解释可以看出,bean是被框架的容器创建的,并且被容器注入到框架内部对象中去。
其实从命名就可以看出来,inject就是注入的意思。当我们把某个对象实例作为参数传入到inject方法中时,框架会扫描该对象内部声明有@Inject注解的字段,方法,构造函数或者是方法参数,并将它们注入容器中的管理对象。
因此,所谓struts2的依赖注入其实就是在需要被注入的字段,方法,构造函数或者方法参数上加上@Inject注解就可以了。
下面,我们来做个例子:
①,我们现在struts.xml中配置一个我们自己定义的bean:
1 <bean type="inject.TestInject" name="testInject" class="inject.TestInject" />
下面是我们自己定义的bean的代码:
1 public class TestInject { 2 public TestInject(){ 3 System.out.println("被初始化了。。。"); 4 } 5 }
注意:这是我们自己定义的哦。
然后,我们在Action类里面定义如下:
1 public class IndexAction extends ActionSupport { 2 3 @Inject(value="testInject")//注意这个地方必须加上value属性,否则框架会按照default值来找bean,就找不到这个bean了。 4 private TestInject ti; 5 9 10 public String execute() { 11 System.out.println(ti); 12 return SUCCESS; 13 } 14 }
然后我们访问这个Action类,控制台输出如下:
我们看到,TestInject类的构造方法被调用了,Action类里的ti变量也有值了,而重要的是我们并没有手动创建TestInject的实例来插入到Action类里面,但是它却有值了。这就是
struts2的依赖注入,是框架在初始化Action类时,通过容器(Container)来帮我们注入了ti实例。
当然,我们一般不会用到struts2的依赖注入功能,因为我们有Spring框架。学习struts2的依赖注入只不过是学习它的设计思想,学习它这么设计的好处。