spring来了-03-bean创建细节

Posted 起今知行 | 思考者 | Freedom

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring来了-03-bean创建细节相关的知识,希望对你有一定的参考价值。

  1. 对象创建:单例/多例  【bean节点的属性scope】
    • scope="singleton", 默认值,即默认是单例     【service/dao/工具类】   
    • scope="prototype",                       多例  【Action】
    •  1 @Test
       2     public void testScope() throws Exception {
       3         ApplicationContext ac = 
       4                 new ClassPathXmlApplicationContext("cn/fuyi/a_helloworld/ApplicationContext.xml");
       5         User user1 = (User)ac.getBean("user");
       6         User user2 = (User)ac.getBean("user");
       7         System.out.println(user1);
       8         System.out.println(user2);
       9         System.out.println(user1 == user2);
      10     }
      11 
      12 /**Output   
      13         当设置 scope="singleton"时
      14     cn.fuyi.a_helloworld.User@70941f0a
      15     cn.fuyi.a_helloworld.User@70941f0a
      16     true
      17         当设置 scope="prototype"时
      18     cn.fuyi.a_helloworld.User@70941f0a
      19     cn.fuyi.a_helloworld.User@c820344
      20     false
      21 */
      test Code
  2. 什么时候创建?
    • scope="singletom",     在启动IOC容器时,就已经创建了bean,且整个应用中只有一个
    • scope="prototype",      在用到的时候,才创建对象
 1 重写User的无参构造函数
 2         public User() {
 3         System.out.println("----user创建----");
 4     }
 5 
 6    
 7      @Test
 8     public void testScope1() throws Exception {
 9         ApplicationContext ac = 
10                 new ClassPathXmlApplicationContext("cn/fuyi/a_helloworld/ApplicationContext.xml");
11         System.out.println("----容器创建----");
12         
13         User user = (User)ac.getBean("user");
14         System.out.println(user);
15     }    
16 /**Output
17 当scope="singleton"时
18      ----user创建----
19      ----容器创建----
20      cn.fuyi.a_helloworld.User@36446fd2  
21  当scope="prototype"时
22       ----容器创建----
23       ----user创建----
24       cn.fuyi.a_helloworld.User@7d311feb  
25 */
test Code

  3. 是否延迟创建,只在scope="singleton"时有效 【bean节点的属性lazy-init】  

    • lazy-init="default" / lazy-init="false"          默认值,在启动IOC容器时,就已经创建了bean,且整个应用中只有一个
    • lazy-init="true"                                        在第一次使用单例对象时,创建对象,只创建一次   

  4.创建对象之后,初始化/销毁   【bean节点的属性init-mothod/destroy-mothod】

    • init-mothod="init_user"                        对应对象的init_user()方法,在对象创建完成之后执行
    • destroy-mothod="destroy_user"            在调用容器对象的destroy()方法时执行,此时容器用实现类,即
    • 亲测:对象创建为单例时两者可正常执行,为多例时每次创建对象后都会执行init-mothod,只后不会执行destroy-mothod.
    •  1 在User对象中添加
       2     public void init_method() {
       3         System.out.println("user对象初始化");
       4     }
       5     
       6     public void destory_method() {
       7         System.out.println("user对象销毁");
       8     }    
       9 
      10         @Test
      11     public void testLazyInit() throws Exception {
      12         //创建容器
      13         ClassPathXmlApplicationContext ac = 
      14                 new ClassPathXmlApplicationContext("cn/fuyi/a_helloworld/ApplicationContext.xml");
      15         System.out.println("----容器创建----");
      16         
      17         //从容器中获取bean
      18         User user = (User)ac.getBean("user");
      19         System.out.println(user);
      20 
      21         
      22         //销毁容器
      23         ac.destroy();
      24     }
      25 /**Output
      26 在scope="singleton"时
      27      ----user创建----
      28     user对象初始化
      29     ----容器创建----
      30     cn.fuyi.a_helloworld.User@46cb560b
      31     user对象销毁 
      32 在scope="prototype"时
      33     ----容器创建----
      34     ----user创建----
      35     user对象初始化
      36     cn.fuyi.a_helloworld.User@60209661
      37 
      38 */
      39 
      40
      test Code

  5.创建对象

    • 使用构造器
    •  1 <!-- 创建对象 -->
       2     <!-- 1.默认使用无参构造器 -->
       3     <bean id="user1" class="cn.fuyi.b_createobject.User"></bean>
       4     
       5     <!-- 2.使用有参构造器 -->
       6     <bean id="user1" class="cn.fuyi.b_createobject.User">
       7         <constructor-arg value="22" index="1" type="java.lang.Integer"></constructor-arg>
       8         <constructor-arg value="Jack" index="0" type="java.lang.String"></constructor-arg>
       9     </bean>
      10     
      11     <bean id="str" class="java.lang.String">
      12         <constructor-arg value="Jacks"></constructor-arg>
      13     </bean>
      14     <bean id="user" class="cn.fuyi.b_createobject.User">
      15         <constructor-arg value="22" index="1" type="java.lang.Integer"></constructor-arg>
      16         <constructor-arg ref="str" index="0" type="java.lang.String"></constructor-arg>
      17     </bean>
      View Code
    • 使用工厂类

       1 <!-- 工厂类创建对象 -->
       2     <!-- 工厂类:实例方法 -->
       3         <!--  先创建工厂类 -->
       4     <bean id="factory" class="cn.fuyi.b_createobject.ObjectFactory"></bean>
       5     <bean id="user1" factory-bean="factory" factory-method="getInstance"></bean>
       6     
       7     <!-- 工厂类:静态方法 
       8         class 指定工厂类型
       9         factory-method 指定静态工厂方法
      10     -->
      11     <bean id="user" class="cn.fuyi.b_createobject.ObjectFactory" factory-method="getStaticInstance"></bean>
      View Code

6.对象属性赋值,即注入依赖关系

    • 使用构造器
    • 使用set方法注入(建议)

 

 1 <!-- 对象属性赋值 -->
 2     <!-- 1.通过构造函数 -->
 3     <bean id="user" class="cn.fuyi.c_setProperty.User">
 4         <constructor-arg index="0" value="Jack" type="java.lang.String"></constructor-arg>
 5         <constructor-arg index="1" value="100" type="java.lang.Integer"></constructor-arg>
 6     </bean>
 7 
 8     <!-- 2.通过set方法给属性注入值 -->
 9     <bean id="user" class="cn.fuyi.c_setProperty.User">
10         <property name="lastName" value="Fuyi"></property>
11         <property name="age" value="100"></property>
12     </bean>
View Code
    • 使用内部bean
      1 <bean id="userAction" class="cn.fuyi.c_setProperty.UserAction" scope="prototype">
      2         <property name="userService">
      3             <bean class="cn.fuyi.c_setProperty.UserService" scope="singleton">
      4                 <property name="userDao">
      5                     <bean class="cn.fuyi.c_setProperty.UserDao" scope="singleton"></bean>
      6                 </property>
      7             </bean>
      8         </property>
      9     </bean>
      View Code
    • 使用p  命名空间给对象属性注入值,【在spring3.0以上版本才可使用】
      1     <bean id="userDao" class="cn.fuyi.c_setProperty.UserDao"></bean>
      2     <bean id="userService" class="cn.fuyi.c_setProperty.UserService" p:userDao-ref="userDao"></bean>
      3     <bean id="userAction" class="cn.fuyi.c_setProperty.UserAction" p:userService-ref="userService"></bean>
      4 
      5 <bean id="user" class="cn.fuyi.c_setProperty.User" p:lastName="fuyi" p:age="110"></bean>
      View Code
    • 自动装配
      1 <!-- 也可以在beans节点的属性default-autowire中统一设置 
      2         byName  根据名称自动装配
      3         byType  根据类型自动装配,必须确保IOC容器中只有一个该类型的对象
      4     -->
      5     <bean id="userDao" class="cn.fuyi.c_setProperty.UserDao"></bean>
      6     <bean id="userService" class="cn.fuyi.c_setProperty.UserService" autowire="byName"></bean>
      7     <bean id="userAction" class="cn.fuyi.c_setProperty.UserAction" autowire="byName"></bean>
      View Code
    • 使用注解(建议)
      • 使用注解步骤
      1. 开启注解扫描
        <context:component-scan base-package="cn.fuyi.c_setProperty"></context:component-scan>
      2. 使用注解    
 1 @Component("userService")    //相当于 [<bean id="userService"  class="" />],在类上加
 2 @Resource(name="userDao")  //相当于 [<property name="userDao" ref="userDao" />]
 3 
 4 
 5 @Component    默认value="userService", 类名,首字母小写
 6 @Resource       默认name="userDao"       类名,首字母小写
 7 
 8 
 9 @Repository     持久层
10 @Service          业务层
11 @Controller      控制层
View Code

       @Resource    根据类型查找

       @Resource(name="userDao")    根据名称查找

 

以上是关于spring来了-03-bean创建细节的主要内容,如果未能解决你的问题,请参考以下文章

Android 逆向使用 Python 解析 ELF 文件 ( Capstone 反汇编 ELF 文件中的机器码数据 | 创建反汇编解析器实例对象 | 设置汇编解析器显示细节 )(代码片段

Spring boot:thymeleaf 没有正确渲染片段

使用 viewpager 创建多个片段

从活动创建片段时getView返回null

Spring--基础细节

spring对bean的管理细节