spring来了-03-bean创建细节
Posted 起今知行 | 思考者 | Freedom
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring来了-03-bean创建细节相关的知识,希望对你有一定的参考价值。
- 对象创建:单例/多例 【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 */
- 什么时候创建?
- 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 */
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
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>
-
使用工厂类
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>
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>
- 使用内部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>
- 使用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>
-
- 自动装配
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>
- 使用注解(建议)
- 使用注解步骤
- 开启注解扫描
<context:component-scan base-package="cn.fuyi.c_setProperty"></context:component-scan>
- 使用注解
- 自动装配
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 控制层
@Resource 根据类型查找
@Resource(name="userDao") 根据名称查找
以上是关于spring来了-03-bean创建细节的主要内容,如果未能解决你的问题,请参考以下文章
Android 逆向使用 Python 解析 ELF 文件 ( Capstone 反汇编 ELF 文件中的机器码数据 | 创建反汇编解析器实例对象 | 设置汇编解析器显示细节 )(代码片段