作者:一杯甜酒
原文:https://blog.csdn.net/u012562943/article/details/51397417
在Spring框架中,无论何时bean被使用时,当仅被调用了一个属性。一个明智的做法是将这个bean声明为内部bean。内部bean可以用setter注入“属性”和构造方法注入“构造参数”的方式来实现。
比如,在我们的应用程序中,一个Customer类引用了一个Person类,我们的要做的是创建一个Person的实例,然后在Customer内部使用。
Spring框架并没有对单例bean进行任何多线程的封装处理。关于单例bean的线程安全和并发问题需要开发者自行去搞定。
但实际上,大部分的Spring bean并没有可变的状态(比如Serview类和DAO类),所以在某种程度上说Spring的单例bean是线程安全的。
如果你的bean有多种状态的话(比如 View Model 对象),就需要自行保证线程安全。
最浅显的解决办法就是将多态bean的作用域由“singleton”变更为“prototype”。
请举例说明如何在Spring中注入一个Java Collection?
Spring提供了以下四种集合类的配置元素:
1、<list> : 该标签用来装配可重复的list值。
2、<set> : 该标签用来装配没有重复的set值。
3、<map>: 该标签可用来注入键和值可以为任何类型的键值对。
4、<props> : 该标签支持注入键和值都是字符串类型的键值对。
第一种方法是使用如下面代码所示的<props> 标签:
<bean
id="adminUser"
class="com.howtodoinjava.common.Customer">
<property
name="emails">
<props>
<prop
key="admin">admin@nospam.com</prop>
<prop
key="support">support@nospam.com</prop>
</props>
</property>
</bean>
也可用”util:”命名空间来从properties文件中创建出一个propertiesbean,然后利用setter方法注入bean的引用。
在Spring框架中,在配置文件中设定bean的依赖关系是一个很好的机制,Spring容器还可以自动装配合作关系bean之间的关联关系。
这意味着Spring可以通过向Bean Factory中注入的方式自动搞定bean之间的依赖关 系。自动装配可以设置在每个bean上,也可以设定在特定的bean上。
下面的XML配置文件表明了如何根据名称将一个bean设置为自动装配:
<bean id="employeeDAO" class="com.howtodoinjava.EmployeeDAOImpl"
autowire="byName" />
除了bean配置文件中提供的自动装配模式,还可以使用@Autowired注解来自动装配指定的bean。在使用@Autowired注解之前需要在按照如下的配置方式在Spring配置文件进行配置才可以使用。
<context:annotation-config />
也可以通过在配置文件中配置AutowiredAnnotationBeanPostProcessor 达到相同的效果。
<bean class ="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
配置好以后就可以使用@Autowired来标注了。
@Autowired
public EmployeeDAOImpl ( EmployeeManager manager ) { this.manager = manager; }
在Spring框架中共有5种自动装配,让我们逐一分析。
1.no:这是Spring框架的默认设置,在该设置下自动装配是关闭的,开发者需要自行在bean定义中用标签明确的设置依赖关系。
2.byName:该选项可以根据bean名称设置依赖关系。当向一个bean中自动装配一个属性时,容器将根据bean的名称自动在在配置文件中查询一个匹配的bean。如果找到的话,就装配这个属性,如果没找到的话就报错。
3.byType:该选项可以根据bean类型设置依赖关系。当向一个bean中自动装配一个属性时,容器将根据bean的类型自动在在配置文件中查询一个匹配的bean。如果找到的话,就装配这个属性,如果没找到的话就报错。
4.constructor:造器的自动装配和byType模式类似,但是仅仅适用于与有构造器相同参数的bean,如果在容器中没有找到与构造器参数类型一致的bean,那么将会抛出异常。
5.autodetect:该模式自动探测使用构造器自动装配或者byType自动装配。首先,首先会尝试找合适的带参数的构造器,如果找到的话就是用构造器自动装配,如果在bean内部没有找到相应的构造器或者是无参构造器,容器就会自动选择byTpe的自动装配方式。
要使用 @Autowired,需要注册 AutowiredAnnotationBeanPostProcessor,可以有以下两种方式来实现:
1、引入配置文件中的<bean>下引入 <context:annotation-config>
<beans> <context:annotation-config /> </beans>
2、在bean配置文件中直接引入AutowiredAnnotationBeanPostProcessor
<beans>
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
</beans>
请举例解释@Required annotation?
在产品级别的应用中,IoC容器可能声明了数十万了bean,bean与bean之间有着复杂的依赖关系。
设值注解方法的短板之一就是验证所有的属性是否被注解是一项十分困难的操作。可以通过在<bean>中设置“dependency-check”来解决这个问题。
在应用程序的生命周期中,你可能不大愿意花时间在验证所有bean的属性是否按照上下文文件正确配置。或者你宁可验证某个bean的特定属性是否被正确的设置。
即使是用“dependency-check”属性也不能很好的解决这个问题,在这种情况下,你需要使用@Required 注解。
需要用如下的方式使用来标明bean的设值方法。
public class EmployeeFactoryBean extends AbstractFactoryBean<Object> {
private String designation;
public String getDesignation() {
return designation;
}
@Required
public void setDesignation(String designation) {
this.designation = designation;
}
//more code here
}
RequiredAnnotationBeanPostProcessor是Spring中的后置处理用来验证被@Required 注解的bean属性是否被正确的设置了。
在使用RequiredAnnotationBeanPostProcesso来验证bean属性之前,首先要在IoC容器中对其进行注册:
<bean class="org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor" />
但是如果没有属性被用 @Required 注解过的话,后置处理器会抛出一个BeanInitializationException 异常。
请举例解释@Autowired注解?
@Autowired注解对自动装配何时何处被实现提供了更多细粒度的控制。
@Autowired注解可以像@Required注解、构造器一样被用于在bean的设值方法上自动装配bean的属性,一个参数或者带有任意名称或带有多个参数的方法。
比如:可以在设值方法上使用@Autowired注解来替代配置文件中的 <property>元素。
当Spring容器在setter方法上找到@Autowired注解时,会尝试用byType 自动装配。
当然我们也可以在构造方法上使用@Autowired 注解。带有@Autowired 注解的构造方法意味着在创建一个bean时将会被自动装配,即便在配置文件中使用<constructor-arg> 元素。
public class TextEditor {
private SpellChecker spellChecker;
@Autowired
public TextEditor(SpellChecker spellChecker){
System.out.println("Inside TextEditor constructor." );
this.spellChecker = spellChecker;
}
public void spellCheck(){
spellChecker.checkSpelling();
}
}
下面是没有构造参数的配置方式:
<beans>
<context:annotation-config/>
<bean id="textEditor" class="com.howtodoinjava.TextEditor"/>
<bean id="spellChecker" class="com.howtodoinjava.SpellChecker"/>
</beans>