Java拾遗之Spring IoC(二)

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(.......) {
          ...
          }
    }   
}

猜你喜欢

转载自blog.csdn.net/jsong1025/article/details/50381309