Java拾遗之Spring IoC(二)
参数注入
注入基本值
<value/>元素可以通过字符串指定属性或构造器参数的值。容器将字符串从java.lang.String类型转化为实际的属性或参数类型后给Bean对象注入.
<bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" >
<property name="username">
<value>root</value>
</property>
<property name="password">
<value>1234</value>
</property>
… …
</bean>
也可以通过value属性指定基本值
<bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" >
<property name="username" value="root"/>
<property name="password" value="1234"/>
… …
</bean>
注入Bean对象
注入Bean对象,定义格式有内部Bean和外部Bean两种
注入内部Bean
<bean id="userService" class="com.service.userService">
<property name="userDAO">
<bean class="com.dao.OralceUserDao"></bean>
</property>
</bean>
注入外部Bean(引用方式, 方便重用)
<bean id="userDAO" class="com.dao.OracleUserDao"/>
<bean id="userService" class="com.service.UserService">
<property name="userDAO" ref="userDAO"/>
</bean>
注入集合
通过<list/>、<set/>、<map/>及<props/>元素可以定义和设置与Java类型中对应List、Set、Map及Properties的属性值。
List集合注入
<bean id="messageBean" class="com.util.MessageBean" >
<property name="friends">
<list>
<value>Jack</value>
<value>Tom</value>
</list>
</property>
… …
</bean>
Set集合注入
<bean id="messageBean" class="com.util.MessageBean" >
<property name="cities">
<set>
<value>北京</value>
<value>上海</value>
<value>广州</value>
</set>
</property>
… …
</bean>
Map集合注入
<bean id="messageBean" class="com.util.MessageBean" >
<property name="books">
<map>
<entry key="1001" value="Java语言基础"></entry>
<entry key="1002" value="Java Web基础"></entry>
<entry key="1003" value="Spring使用基础"></entry>
</map>
</property>
… …
</bean>
Properties集合注入
<bean id="messageBean" class="com.util.MessageBean" >
<property name="dbParams">
<props>
<prop key="username">root</prop>
<prop key="password">1234</prop>
<prop key="driverClassName">com.mysql.jdbc.Driver</prop>
</props>
</property>
… …
</bean>
引用方式List集合注入
<util:list id="oneList">
<value>Jack</value>
<value>Tom</value>
</util:list>
<bean id="messageBean" class="com.util.MessageBean" >
<property name="friends" ref="oneList">
… …
</bean>
Set Map Properties 都可以采用引用方式注入
<util:list /> <util:set/> <util:props />
注入Spring表达式值
Spring引入了一种表达式语言,这和统一的EL在语法上很相似,这种表达式语言可以用于定义基于XML和注解配置的Bean,注入一个properties文件信息。
<util:properties id="jdbcProperties" location="classpath:org/config/jdbc.properties"/>
<bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" >
<property name="username" value=" #{jdbcProperties.username} "/>
<property name="password" value=" #{jdbcProperties.password} "/>
… …
</bean>
注入null或空字符串
Spring将属性的空参数当作空String,下面给email属性设置了空String值(”“)
<bean id="exampleBean" class="com.bean.ExampleBean">
<property name="email" value=""/>
</bean>
如果需要注入null值,可以使用<null/>元素
<bean id="exampleBean" class="com.bean.ExampleBean">
<property name="email">
<null/>
</property>
</bean>
基于注解的组件扫描
什么是组件扫描
指定一个包路径,Spring会自动扫描该包及其子包所有组件类,当发现组件类定义前有特定的注解标记时,就将该组件纳入到Spring容器。等价于原有XML配置中的<bean>定义功能。
组件扫描可以替代大量XML配置的<bean>定义。
指定扫描类路径
使用组件扫描,首先需要在XML配置中指定扫描类路径
<context:component-scan base-package="org.example"/>
上面配置,容器实例化时会自动扫描org.example包及其子包下所有组件类。
自动扫描的注解标记
指定扫描类路径后,并不是该路径下所有组件类都扫描到Spring容器的,只有在组件类定义前面有以下注解标记时,才会扫描到Spring容器。
注解标记 | 描述 |
---|---|
@Component | 通用注解 |
@Name | 通用注解 |
@Repository | 持久层组件注解 |
@Service | 业务层组件注解 |
@Controller | 控制层组件注解 |
自动扫描组件的命名
当一个组件在扫描过程中被检测到时,会生成一个默认id值,默认id为小写开头的类名。也可以在注解标记中自定义id。下面两个组件id名字分别是oracleUserDao和loginService
@Repository
public class OracleUserDao implements UserDao {
// ...
}
@Service("loginService")
public class UserService {
// ...
}
指定组件的作用域
通常受Spring管理的组件,默认的作用域是”singleton”。如果需要其他的作用域可以使用@Scope注解,只要在注解中提供作用域的名称即可。
@Scope("prototype")
@Repository
public class OracleUserDao implements EmpDao {
// ...
}
初始化销毁与回调控制
@PostConstruct和@PreDestroy注解标记分别用于指定初始化和销毁回调方法,使用示例:
public class ExampleBean {
@PostConstruct
public void init() {
//初始化回调方法
}
@PreDestroy
public void destroy() {
//销毁回调方法
}
}
指定依赖注入关系
具有依赖关系的Bean对象,利用下面任意一种注解都可以实现关系注入
@Resource
@Autowired/@Qualifier
@Inject/@Named
@Resource注解标记可以用在字段定义或setter方法定义前面,默认首先按名称匹配注入,然后类型匹配注入
public class UserService {
//@Resource
private UserDao userDao;
@Resource
public void setUserDao(UserDao dao) {
this.userDao = dao;
}
}
当遇到多个匹配Bean时注入会发生错误,可以显式指定名称,例如@Resource(name=”empDao1”)
@Autowired注解标记也可以用在字段定义或setter方法定义前面,默认按类型匹配注入
public class UserService {
//@Autowired
private UserDao userDao;
@Autowired
public void setUserDao(UserDao dao) {
this.userDao = dao;
}
}
@Autowired当遇到多个匹配Bean时注入会发生错误,可以使用下面方法指定名称
public class UserService {
//@Autowired
//@Qualifier("mysqlUserDao")
private UserDao userDao;
@Autowired
public void setUserDao(@Qualifier(“mysqlUserDao”) userDao dao){
this.userDao = dao;
}
}
@Inject注解标记是Spring3.0开始增添的对JSR-330标准的支持,使用前需要添加JSR-330的jar包,使用方法与@Autowired相似,具体如下
public class UserService {
// @Inject
private UserDao userDao;
@Inject
public void setUserDao(UserDao dao) {
this.userDao = dao;
}
}
@Inject当遇到多个匹配Bean时注入会发生错误,可以使用@Named指定名称限定,使用方法如下
public class UserService {
private UserDao userDao;
@Inject
public void setUserDao(@Named(“mysqlUserDao”)
UserDao dao){
this.userDao = dao;
}
}
注入Spring表达式
@Value注解可以注入Spring表达式值,使用方法
首先在XML配置中指定要注入的properties文件
<util:properties id="jdbcProps" location="classpath:db.properties"/>
然后在setter方法前使用@Value注解
public class JDBCDataSource{
@Value("#{jdbcProps.url}")
private String url;
@Value("#{jdbcProps.driver}")
public void setUrl(String driver) {
try{
Class.forName(driver)
} catch(.......) {
...
}
}
}