Spring03:注入(Injection)

目录

1.注入

1.什么是注入:

通过Spring工厂及配置文件,为所创建对象的成员变量赋值。

2.为什么需要注入

以前我们为对象的成员变量赋值,直接通过编码的方式,这样是存在耦合的
Spring03:注入(Injection)
如果我们以后想为name属性,设置别的值。那么又要改代码,存在耦合性,所以我们将对象属性的设置放到配置文件中(属性注入)。

3.如何进行注入(开发步骤)

  • 类的成员变量提供set get方法
  • 配置spring的配置文件
     <bean id="person" name="p1,p2" class="com.baizhiedu.basic.model.Person">
         <property name="id">
             <value>10</value>
         </property>
         <property name="name">
             <value>*</value>
         </property>
     </bean>
    

4.注入的好处:

解耦合:日后属性需要改动的话,就不需要在代码层面修改了,到配置文件中修改。

2.注入原理分析(简易版)

1.类似前面的工厂原理分析:会根据配置文件,进行反射创建对象(最终调用构造方法)。注入会根据配置文件内容的property标签,调用set方法对属性赋值。

  • Spring通过底层调用对象属性的set方法,完成成员变量的赋值,这种方法我们也称之为set注入
  • 会根据配置文件内容的property标签,调用set方法对属性赋值。

Spring03:注入(Injection)

3.Set注入详解

1.针对不同类型的成员变量,我们在注入时,在<property>标签中,需要嵌套不同的子标签。

2.可能遇到的各种Set注入的类型主要分为两大类

  • JDK内置类型
  • 用户自定义类型
    Spring03:注入(Injection)

3.1.Set注入JDK内置类型

Spring03:注入(Injection)

1.8种基本类型+String

基本类型:字符类型char,布尔类型boolean以及数值类型byte、short、int、long、float、double。

property标签直接嵌套value标签

<bean id="person" name="p1,p2" class="com.baizhiedu.basic.model.Person">
	<property name="id">
	    <value>10</value>
	</property>
</bean>	

2.数组类型:

property标签嵌套list标签,list标签再嵌套value标签

//Person类数组属性
 private String[] email;

 public String[] getEmail() {
     return email;
 }

 public void setEmail(String[] email) {
     this.email = email;
 }

//applicationContext.xml
<bean id="person" name="p1,p2" class="com.baizhiedu.basic.model.Person"> 
 <property name="email">
     <list>
         <value>sdaS@1.com</value>
         <value>sdaS@2.com</value>
         <value>sdaS@3.com</value>
     </list>
 </property>
</bean>

3.Set集合属性:

  • 1.注意Set集合是无序的
//Person类Set属性
 private Set<String> tels;

 public Set<String> getTels() {
     return tels;
 }

 public void setTels(Set<String> tels) {
     this.tels = tels;
 }

//applicationContext.xml
<bean id="person" name="p1,p2" class="com.baizhiedu.basic.model.Person"> 
   <property name="tels">
       <set>
           <value>12312311313</value>
           <value>12666611313</value>
           <value>12789011313</value>
       </set>
   </property>
</bean>
  • 2.注意:set标签里面不一定嵌套value,要根据Set<>泛型来决定。如果没有指定泛型,说明可以存任何对象,那么set标签可以同时嵌套value(8种基本类型+String),list(数组,list),ref标签(自定义对象)。
//Person类Set属性
 private Set obj;

 get/set

//applicationContext.xml
<bean id="person" name="p1,p2" class="com.baizhiedu.basic.model.Person"> 
   <property name="tels">
       <set>
           <value>12312311313</value>
           <ref bean="idz值"/>
           <list>
           	<value>12313</value>
           </list>
       </set>
   </property>
</bean>

4.List集合属性

  • property标签嵌套list标签(同数组,因为list底层用的就是数组),list中嵌套的标签要根据List< E >泛型来决定。
  • 注意:list元素是允许重复的,而且是有序的,输出顺序同赋值时的顺序。
<bean id="person" name="p1,p2" class="com.baizhiedu.basic.model.Person"> 
   <property name="address">
		<list>
		   <value>11111</value>
		   <value>2222</value>
		   <value>2222</value>
		</list>
   </property>
</bean>

5.Map集合属性

  • Map的特点:键值对,每对键值对又是一个Map.Entry对象。
  • key有特定的子标签,子标签根据对应的泛型类型选择;值没有子标签,且要根据对应的泛型类型选择。
  • 注意:为什么在key标签和entry标签中嵌套了value标签,因为Map< String, String>属性的泛型是String, String。
  • key标签的value标签:表示键的value;entry标签的value标签:表示值的value
<property name="qqs">
    <map>
        <entry>
            <key><value>txl</value></key>
            <value>1309984539</value>
        </entry>
        <entry>
            <key><value>others</value></key>
            <value>9999999</value>
        </entry>
    </map>
</property>

6.Properties集合属性

后面进行Spring与MyBatis的整合,需要大量的使用这个类型。

  • Properties类型是一种特殊的Map:key和value都只能是String。
  private Properties properties;

  public Properties getProperties() {
      return properties;
  }

  public void setProperties(Properties properties) {
      this.properties = properties;
  }
  
  <property name="properties">
      <props>
          <prop key="sss">wwww</prop>
          <prop key="eee">tttt</prop>
      </props>
  </property>

7.复杂的JDK类型(Date)

需要自定义类型转换器来处理。

3.2.Set注入用户自定义类型

Spring03:注入(Injection)
1.第一种方式:

  • 为成员变量提供set get方法

    public class UserServiceImpl implements UserService {
    
          private UserDAO userDao;
      
          public UserDAO getUserDao() {
              return userDao;
          }
      
          public void setUserDao(UserDAO userDao) {
              this.userDao = userDao;
          }
      
          @Override
          public void register(User user) {
              userDao.register(user);
          }
      
          @Override
          public void login(String name, String password) {
              userDao.login(name, password);
          }
      }
    
  • 配置文件中进行注入(赋值)

      <bean id="userService" class="com.baizhiedu.basic.UserServiceImpl">
          <property name="userDao">
              <bean class="com.baizhiedu.basic.UserDAOImpl"></bean>
          </property>
      </bean>
    
  • 第一种赋值方式存在的问题:

    • 1.配置文件代码冗余:AServiceImpl需要userDao属性,BServiceImpl也需要userDao属性,那么配置文件中就需要写两句<bean class="com.baizhiedu.basic.UserDAOImpl"></bean>。如果更多的Service对象需要这个属性,配置文件中就需要写更多。

Spring03:注入(Injection)

    • 2.每写一个bean标签就意味着创建了一个UserDao对象,所以被注入的对象属性(UserDao)多次创建,浪费(JVM内存资源)。

2.第二种方式:

  • 注意:< ref bean=“userDao”>< /ref>中的bean属性是其他bean标签的id值。
 <bean id="userDao" class="com.baizhiedu.basic.UserDAOImpl"></bean>
 <bean id="userService" class="com.baizhiedu.basic.UserServiceImpl">
     <property name="userDao">
         <ref bean="userDao"></ref>
     </property>
 </bean>

Spring03:注入(Injection)

  • 注意:Spring4.x废除了< ref local = “”/>,这个语法基本等效于< ref bean=""/>

3.3.Set注入的简化写法

1.基于属性的简化:

  1. value属性,代替value标签:value属性只能用在JDK的八种基本类型+String类型。
        <property name="id">
            <value>10</value>
        </property>
        //value属性,代替value标签
        <property name="id" value="10"></property>

		
		<property name="userDAO">
		   <ref bean="userDAO"/>
		</property>
		//ref属性代替ref标签
		<property name="userDAO" ref="userDAO"/>

2.基于命名空间p的简化:

Spring03:注入(Injection)
Spring03:注入(Injection)
命名空间p就相当于property标签的作用:
Spring03:注入(Injection)
配置文件写法:

<bean id="person1" class="com.baizhiedu.basic.model.Person" p:name="tttxxxll" p:id="66666"></bean>

//等价于
<bean id="person1" class="com.baizhiedu.basic.model.Person">
   <property name="id" value="66666"></property>
   <property name="name">
       <value>tttxxxll</value>
   </property>
</bean>


<bean id="userDao" class="com.baizhiedu.basic.UserDAOImpl"></bean>
<bean id="userService1" class="com.baizhiedu.basic.UserServiceImpl" p:userDao-ref="userDao"/>
//等价于原写法
<bean id="userService" class="com.baizhiedu.basic.UserServiceImpl">
    <property name="userDao">
        <!--<bean class="com.baizhiedu.basic.UserDAOImpl"></bean>-->
        <ref bean="userDao"></ref>
    </property>
</bean>
上一篇:DVWA1.10_Command_Injection


下一篇:CGCTF——GBK Injection