• Spring框架总结(三)——bean标签和依赖注入


    一、bean 标签和管理对象细节


    1.1 bean 标签

    作用:

      用于配置对象让spring来创建的。

      默认情况下它调用的是类中的无参构造函数。如果没有无参构造函数则不能创建成功。

    属性:

      id:给对象在容器中提供一个唯一标识。用于获取对象。

      class:指定类的权限定类名。用于反射创建对象。默认情况下调用无参构造函数。

      scope:指定对象的作用范围。

        * singleton:默认值,单例的。

        * prototype:多例的

      init-method:指定类中的初始化方法名称。

      destory-method:指定类中销毁方法名称。

    1.2 bean的作用范围和生命周期

    单列对象:scope="singleton"

      一个应用只有一个对象的实例。它的作用范围就是整个引用。

      生命周期:

        对象出生:当应用加载时,创建容器时,对象就被创建了。

        对象活着:只有容器在,对象一直活着。

        对象死亡:当应用卸载,销毁容器时,对象就被销毁了。

    多例对象:scope="prototype"

      每次访问对象时,都会重新创建对象实例。

      生命周期:

        对象出生:当使用对象时,创建新的对象实例。

        对象活着:只要对象在使用中,就一直活着。

        对象死亡:当对象长时间不用时,被java的垃圾回收器回收了。

    演示:单例和多例对象

    第一步:编写IUserService接口

    1 package com.justnow.service;
    2 
    3 public interface IUserService {
    4     public void findAll();
    5 }

    第二步:编写UserServiceImpl实现类

     1 package com.justnow.service.impl;
     2 
     3 import com.justnow.service.IUserService;
     4 
     5 public class UserServiceImpl implements IUserService {
     6 
     7     public void findAll() {
     8         System.out.println("假装打印了数据库中的所有数据");
     9     }
    10 }

    第三步:编写spring配置文件

    1 <?xml version="1.0" encoding="UTF-8"?>
    2 <beans xmlns="http://www.springframework.org/schema/beans"
    3        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4        xsi:schemaLocation="http://www.springframework.org/schema/beans
    5        http://www.springframework.org/schema/beans/spring-beans.xsd">
    6     <!--配置 service -->
    7     <bean id="userService" class="com.justnow.service.impl.UserServiceImpl" scope="singleton"/>
    8 </beans>

    这里配置scope为单例对象

    第四步:测试

     1 package com.justnow.test;
     2 
     3 import com.justnow.service.IUserService;
     4 import org.junit.Test;
     5 import org.springframework.context.support.ClassPathXmlApplicationContext;
     6 
     7 public class Test01 {
     8     @Test
     9     public void testBean(){
    10         ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
    11         IUserService userService = (IUserService) context.getBean("userService");
    12         IUserService userService1 = (IUserService) context.getBean("userService");
    13         System.out.println(userService);
    14         System.out.println(userService1);
    15     }
    16 }

    单例测试结果:

    userService和userService2,打印出来的结果是一致的!

    双例测试结果:

    修改scope为"prototype"

    1.3 实例化bean的三种方式

    第一种方式:使用默认无参构造函数

    会根据默认无参构造函数来创建类对象。如果bean中没有默认无参构造函数,将会创建失败。

    如:

    1 <bean id="userService" class="com.justnow.service.impl.UserServiceImpl" />

    此时UserServiceImpl中必须有无参的构造函数。

    第二种方式:spring管理静态工厂-使用静态工厂的方法创建对象

    模拟一个静态工厂,创建业务层实现类

     1 package com.justnow.factory;
     2 
     3 import com.justnow.service.IUserService;
     4 import com.justnow.service.impl.UserServiceImpl;
     5 
     6 public class StaticFactory {
     7     public static IUserService createUserService(){
     8         return new UserServiceImpl();
     9     }
    10 }

    bean的配置,使用StaticFactory类中的静态方法createUserService创建对象,并存入spring容器:

    id 属性:指定bean的id,用于从容器中获取

    class属性:指定静态工厂的全限定类名

    factory-method 属性:指定生产对象的静态方法

    1 <bean id="userService" class="com.justnow.factory.StaticFactory" factory-method="createUserService" />

    第三种方式:spring管理实例工厂-使用实例工厂的方法创建对象

    先把工厂的创建交给spring来管理。然后在使用工厂的bean来调用里面的方法

    factory-bean属性:用来指定实例工厂beand的id。

    factory-method属性:用于指定实例工厂中创建对象的方法。

    模拟一个实例工厂,创建业务层实现类

    此工厂创建对象,必须现有工厂实例对象,再调用方法

     1 package com.justnow.factory;
     2 
     3 import com.justnow.service.IUserService;
     4 import com.justnow.service.impl.UserServiceImpl;
     5 
     6 /**
     7  * 模拟一个实例工厂,创建业务层实现类
     8  * 此工厂创建对象,必须有工厂实例对象,再调用方法
     9  */
    10 public class InstanceFactory {
    11     public IUserService createUserService(){
    12         return new UserServiceImpl();
    13     }
    14 }

    bean的配置文件

        <!--第三种方式,spring管理实例工厂,使用实例工厂的方法创建对象-->
        <bean id="instanceFactory" class="com.justnow.factory.InstanceFactory"/>
        <bean id="userService" factory-bean="instanceFactory" factory-method="createUserService" />

    https://github.com/justn0w/javawebdemo/tree/master/spring/Spring_demo2 

    d20c371406409b204c554c0a41c91ad5b6b86de1

    二、spring的依赖注入

    2.1 什么是依赖注入:

    依赖注入:Dependency Injection。它是spring框架核心IoC的具体实现。

    我们的程序在编写时,通过控制反转,把对象的创建交给了spring,但是在代码中不可能出现没有依赖的情况。IoC解耦只是降低他们的依赖关系。

    但不会消除。例如:我们的业务层仍会调用持久层的方法。简单的说就是spring框架把持久层对象传入业务层,而不用我们自己去获取。

    2.2 通过构造函数实现依赖注入

    使用类中的构造函数,给成员变量赋值。赋值操作是由spring框架来为我们注入的。

    UserServiceImpl实现类:

    该类共有三个属性,分别是name,age,birthday;

     1 package com.justnow.service.impl;
     2 
     3 import com.justnow.service.IUserService;
     4 
     5 import java.util.Date;
     6 
     7 public class UserServiceImpl implements IUserService {
     8 
     9     private String name;
    10     private Integer age;
    11     private Date birthdy;
    12 
    13     public UserServiceImpl() {
    14     }
    15 
    16     public UserServiceImpl(String name, Integer age, Date birthdy){
    17         this.name = name;
    18         this.age = age;
    19         this.birthdy = birthdy;
    20     }
    21 
    22     public void save(){
    23         System.out.println(name+","+age+","+birthdy);
    24     }
    25 
    26 /*    public void findAll() {
    27         System.out.println("假装打印了数据库中的所有数据");
    28     }*/
    29 }

    在配置文件中赋值:

    applicationContext.xml

    1     <!--通过构造函数实现依赖注入-->
    2     <bean id="userService" class="com.justnow.service.impl.UserServiceImpl" >
    3         <constructor-arg name="name" value="张三"></constructor-arg>
    4         <constructor-arg name="age" value="18"></constructor-arg>
    5         <constructor-arg name="birthdy" ref="now"></constructor-arg>
    6     </bean>
    7     <bean id="now" class="java.util.Date" />

    使用构造函数的方式,给service中的属性赋值

    要求:类中需要提供一个对应参数列表的构造函数

    标签:constructor-arg

      属性:index:指定参数在构造函数列表的索引位置

         type:指定参数在构造函数中的数据类型

         name:指定参数在构造函数中的名称

         value:给name属性赋值,前提是基本数据类型和String类型

         ref:同样的是给name赋值,但是该值是bean类型,必须在配置文件中配置。如上例中的id为now的bean标签

    本小节代码:

    https://github.com/justn0w/javawebdemo/tree/master/spring/Spring_demo2

    2e64f8d7cf0a7a1f710e8abfc3d9707653b5063a

    2.2 set 方法注入

     在UserServiceImpl实现类中,设置属性的set的方法即可代码,如下:

     1 package com.justnow.service.impl;
     2 
     3 import com.justnow.service.IUserService;
     4 
     5 import java.util.Date;
     6 
     7 public class UserServiceImpl implements IUserService {
     8 
     9     private String name;
    10     private Integer age;
    11     private Date birthdy;
    12 
    13     //set 方法注入
    14     public void setName(String name) {
    15         this.name = name;
    16     }
    17 
    18     public void setAge(Integer age) {
    19         this.age = age;
    20     }
    21 
    22     public void setBirthdy(Date birthdy) {
    23         this.birthdy = birthdy;
    24     }
    25 
    26     public void save(){
    27         System.out.println(name+","+age+","+birthdy);
    28     }
    29     
    30 }

    同时还需要修改spring的配置文件

     1     <!--通过set方法实现依赖注入-->
     2     <!-- 通过配置文件给 bean 中的属性传值:使用 set 方法的方式
     3     涉及的标签:
     4         property
     5     属性:
     6         name:找的是类中 set 方法后面的部分
     7         ref:给属性赋值是其他 bean 类型的
     8         value:给属性赋值是基本数据类型和 string 类型的
     9     实际开发中,此种方式用的较多。
    10 -->
    11     <bean id="userService" class="com.justnow.service.impl.UserServiceImpl">
    12         <property name="name" value="test"/>
    13         <property name="age" value="21"/>
    14         <property name="birthdy" ref="now" />
    15     </bean>
    16 
    17     <bean id="now" class="java.util.Date" />

    测试结果:

     https://github.com/justn0w/javawebdemo/tree/master/spring/Spring_demo2

    fe6038b18cff7d32c1b4515bf53bea9c8b0bdd0e

    2.2 使用p名称空间注入数据

    在xml中导入p名称空间,使用p:propertyName来注入数据,本质仍然是调用类中的set方法实现注入功能。

    所以,UserServiceIpml实现类,不需要改变。只需要修改spring的配置文件即可

    第一步:修改xml的命名空间,即添加p命名空间

    添加了一句:

    xmlns:p="http://www.springframework.org/schema/p"

    第二步:在bean中使用p标签给属性赋值

    1 <bean id="userService" class="com.justnow.service.impl.UserServiceImpl" p:name="testp" p:age="23" p:birthdy-ref="now"/>
    2 <bean id="now" class="java.util.Date" />

    测试结果:

     47e50fff82f0cee3155226f620a00989da3828a6

    2.3 注入集合属性

    考虑到某些情况下需要一些类型为集合的属性,接下来就演示下,如何注入集合属性的。其本质还是通过set方法注入属性的

    第一步:在实现类中添加数组、List、set、Map、Properties等数据类型的属性。

     1 package com.justnow.service.impl;
     2 
     3 import com.justnow.service.IUserService;
     4 
     5 import java.util.*;
     6 
     7 public class UserServiceImpl2 implements IUserService {
     8 
     9     private String[] myStrs;
    10     private List<String> myList;
    11     private Set<String> mySet;
    12     private Map<String, String> myMap;
    13     private Properties myProps;
    14 
    15     public void setMyStrs(String[] myStrs) {
    16         this.myStrs = myStrs;
    17     }
    18 
    19     public void setMyList(List<String> myList) {
    20         this.myList = myList;
    21     }
    22 
    23     public void setMySet(Set<String> mySet) {
    24         this.mySet = mySet;
    25     }
    26 
    27     public void setMyMap(Map<String, String> myMap) {
    28         this.myMap = myMap;
    29     }
    30 
    31     public void setMyProps(Properties myProps) {
    32         this.myProps = myProps;
    33     }
    34 
    35 
    36     public void save() {
    37         System.out.println(Arrays.toString(myStrs));
    38         System.out.println(myList);
    39         System.out.println(mySet);
    40         System.out.println(myMap);
    41         System.out.println(myProps);
    42     }
    43 }

    第二步:修改spring配置文件

      1 <?xml version="1.0" encoding="UTF-8"?>
      2 <beans xmlns="http://www.springframework.org/schema/beans"
      3        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      4        xmlns:p="http://www.springframework.org/schema/p"
      5        xsi:schemaLocation="http://www.springframework.org/schema/beans
      6        http://www.springframework.org/schema/beans/spring-beans.xsd">
      7     <!--配置 service -->
      8 <!-- 第一种方式,使用默认无参构造函数
      9     <bean id="userService" class="com.justnow.service.impl.UserServiceImpl" scope="prototype"/>
     10 -->
     11     <!--第二种方式,spring管理静态工厂-使用静态工厂的方法对象创建-->
     12 <!--
     13     <bean id="userService" class="com.justnow.factory.StaticFactory" factory-method="createUserService" />
     14 -->
     15     <!--第三种方式,spring管理实例工厂,使用实例工厂的方法创建对象-->
     16 <!--
     17     <bean id="instanceFactory" class="com.justnow.factory.InstanceFactory"/>
     18     <bean id="userService" factory-bean="instanceFactory" factory-method="createUserService" />
     19 -->
     20 
     21     <!--通过构造函数实现依赖注入-->
     22 <!--
     23     <bean id="userService" class="com.justnow.service.impl.UserServiceImpl" >
     24         <constructor-arg name="name" value="张三"></constructor-arg>
     25         <constructor-arg name="age" value="18"></constructor-arg>
     26         <constructor-arg name="birthdy" ref="now"></constructor-arg>
     27     </bean>
     28     <bean id="now" class="java.util.Date" />
     29 -->
     30     <!--通过set方法实现依赖注入-->
     31     <!-- 通过配置文件给 bean 中的属性传值:使用 set 方法的方式
     32     涉及的标签:
     33         property
     34     属性:
     35         name:找的是类中 set 方法后面的部分
     36         ref:给属性赋值是其他 bean 类型的
     37         value:给属性赋值是基本数据类型和 string 类型的
     38     实际开发中,此种方式用的较多。
     39 
     40     <bean id="userService" class="com.justnow.service.impl.UserServiceImpl">
     41         <property name="name" value="test"/>
     42         <property name="age" value="21"/>
     43         <property name="birthdy" ref="now" />
     44     </bean>
     45 
     46     <bean id="now" class="java.util.Date" />
     47 -->
     48     <!--使用p命名空间-->
     49 <!--
     50     <bean id="userService" class="com.justnow.service.impl.UserServiceImpl" p:name="testp" p:age="23" p:birthdy-ref="now"/>
     51     <bean id="now" class="java.util.Date" />
     52 -->
     53     <!-- 注入集合数据
     54         List 结构的:
     55             array,list,set
     56         Map 结构的
     57             map,entry,props,prop
     58 -->
     59     <bean id="userService" class="com.justnow.service.impl.UserServiceImpl2">
     60         <!-- 在注入集合数据时,只要结构相同,标签可以互换 -->
     61         <!-- 给数组注入数据 -->
     62         <property name="myStrs">
     63             <array>
     64                 <value>AAA</value>
     65                 <value>BBB</value>
     66                 <value>CCC</value>
     67             </array>
     68         </property>
     69         <!-- 注入 list 集合数据 -->
     70         <property name="myList">
     71             <list>
     72                 <value>AAA</value>
     73                 <value>BBB</value>
     74                 <value>CCC</value>
     75             </list>
     76         </property>
     77         <!-- 注入 set 集合数据 -->
     78         <property name="mySet">
     79             <set>
     80                 <value>AAA</value>
     81                 <value>BBB</value>
     82                 <value>CCC</value>
     83             </set>
     84         </property>
     85         <!-- 注入 Map 数据 -->
     86         <property name="myMap">
     87             <props>
     88                 <prop key="testA">aaa</prop>
     89                 <prop key="testB">bbb</prop>
     90             </props>
     91         </property>
     92         <!-- 注入 properties 数据 -->
     93         <property name="myProps">
     94             <map>
     95                 <entry key="testA" value="aaa"></entry>
     96                 <entry key="testB">
     97                     <value>bbb</value>
     98                 </entry>
     99             </map>
    100         </property>
    101     </bean>
    102 </beans>

    77a345e6da51295e1aa4c5e8c25038e23da3f6ec

    总结:


    1、这些内容在将来的开发过程中会很少用到,但是,还是梳理一下。

      

  • 相关阅读:
    JVM 体系结构
    字符集和编码
    Thinking in Java 笔记
    HSDB
    jdb
    JVM-Class文件
    JVM-操作码助记符
    表、栈和队列
    算法分析
    Shell 编程
  • 原文地址:https://www.cnblogs.com/justn0w/p/11481244.html
Copyright © 2020-2023  润新知