Spring入门之四-------SpringIoC之其他知识点
一、懒加载
public class Bean1 { public Bean1() {
System.out.println(this.getClass().getSimpleName() + ":" + this.toString() + " has been created");
}
}
Bean1
public class Bean2 { public Bean2() {
System.out.println(this.getClass().getSimpleName() + ":" + this.toString() + " has been created");
}
}
Bean2
<bean id="bean1" class="com.imooc.springClass4.others.Bean1" lazy-init="false"/>
<bean id="bean2" class="com.imooc.springClass4.others.Bean2" lazy-init="true"/>
@Test
public void testBean() throws Exception {
final AbstractApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
System.out.println("============ApplicationContext has been create============"); Bean1 bean1 = context.getBean("bean1", Bean1.class);
System.out.println("bean1 = " + bean1);
System.out.println(); Bean2 bean2 = context.getBean("bean2", Bean2.class);
System.out.println("bean2 = " + bean2);
System.out.println();
}
输出
Bean1:com.imooc.springClass4.others.Bean1@49438269 has been created
============ApplicationContext has been create============
bean1 = com.imooc.springClass4.others.Bean1@49438269 Bean2:com.imooc.springClass4.others.Bean2@2462cb01 has been created
bean2 = com.imooc.springClass4.others.Bean2@2462cb01
结论:bean1没有设定懒加载,所以Spring在加载上下文的时候就已经创建了bean1;bean2没有设定懒加载,所以bean2在被需要的时候才创建。
如果想设定当前xml中所有的bean都默认开启懒加载,可通过设定default-lazy-init="false"实现:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd"
default-lazy-init="false"
>
...
</beans>
二、Bean别名
public class Bean3 { public Bean3() {
System.out.println(this.getClass().getSimpleName() + ":" + this.toString() + " has been created");
}
}
Bean3
方式一:通过name属性创建别名
<bean id="bean3-1" name="bean3-2, bean3-3" class="com.imooc.springClass4.others.Bean3"/>
上面代码表示:创建一个Bean3,id为bean3-1,再给取两个别名:bean3-2、bean3-3
方式二:通过alias标签创建别名
<alias name="bean3-1" alias="bean3-4"/>
上面代码表示:给bean3-1取一个别名:bean3-4
测试
@Test
public void testBean() throws Exception {
final AbstractApplicationContext context = new ClassPathXmlApplicationContext("spring.xml"); Bean3 bean3_1 = context.getBean("bean3-1", Bean3.class);
System.out.println("bean3_1 = " + bean3_1);
System.out.println(); Bean3 bean3_2 = context.getBean("bean3-2", Bean3.class);
System.out.println("bean3_2 = " + bean3_2);
System.out.println(); Bean3 bean3_3 = context.getBean("bean3-3", Bean3.class);
System.out.println("bean3_3 = " + bean3_3);
System.out.println(); Bean3 bean3_4 = context.getBean("bean3-4", Bean3.class);
System.out.println("bean3_4 = " + bean3_4);
System.out.println();
}
输出
bean3_1 = com.imooc.springClass4.others.Bean3@1190200a
bean3_2 = com.imooc.springClass4.others.Bean3@1190200a
bean3_3 = com.imooc.springClass4.others.Bean3@1190200a
bean3_4 = com.imooc.springClass4.others.Bean3@1190200a
可以看到所有的bean3_?的地址都是一样的。
三、引入其他xml
public class Bean4 { public Bean4() {
System.out.println(this.getClass().getSimpleName() + ":" + this.toString() + " has been created");
}
}
Bean4
resources目录下创建spring-1.xml,代码如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="bean4" class="com.imooc.springClass4.others.Bean4"/>
</beans>
调整之前的spring.xml,增加
<import resource="spring-1.xml"/>
测试
@Test
public void testBean() throws Exception {
final AbstractApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
Bean4 bean4 = context.getBean("bean4", Bean4.class);
System.out.println("bean4 = " + bean4);
System.out.println();
}
输出
bean4 = com.imooc.springClass4.others.Bean4@6a2f6f80
可以看到我们通过new ClassPathXmlApplicationContext("spring.xml")的方式引用spring.xml,由于spring.xml中import了spring-1.xml,所以spring-1.xml中定义的bean4也被实例化了。
四、方法注入
可能存在如下场景:Class A 的某个方法依赖于Class B的实例,Class A使用scope=singleton单例模式,但是Class A每次执行方法的时候都希望获取一个新的Class B的实例,这个时候就用到了方法注入。举例:
public class Bean5 {
public Bean5() {
System.out.println(this.getClass().getSimpleName() + ":" + this.toString() + " has been created");
}
}
public abstract class Bean6 { public Bean6() {
System.out.println(this.getClass().getSimpleName() + ":" + this.toString() + " has been created");
} protected abstract Bean5 createBean5(); public void printBean5() {
System.out.println("createBean5().toString() = " + createBean5().toString());
}
}
从上面代码我们看到,Bean6的printBean5方法是依赖于Bean5的实例的,如果该方法每次执行都想获得一个Bean5的实例,那么:
- Bean6中声明一个abstract方法,返回Bean5
- Bean6的printBean5方法需要使用Bean5时直接饮用上面的abstract方法
xml配置如下:注意bean5需要时prototype模式
<bean id="bean5" class="com.imooc.springClass4.others.Bean5" scope="prototype"/>
<bean id="bean6" class="com.imooc.springClass4.others.Bean6">
<lookup-method name="createBean5" bean="bean5"/>
</bean>
测试:
@Test
public void testBean() throws Exception {
final AbstractApplicationContext context = new ClassPathXmlApplicationContext("spring.xml"); for (int i = 0; i < 10; i++) {
Bean6 bean6 = context.getBean("bean6", Bean6.class);
bean6.printBean5();
}
}
输出:
Bean5:com.imooc.springClass4.others.Bean5@19b843ba has been created
createBean5().toString() = com.imooc.springClass4.others.Bean5@19b843ba
Bean5:com.imooc.springClass4.others.Bean5@64ec96c6 has been created
createBean5().toString() = com.imooc.springClass4.others.Bean5@64ec96c6
Bean5:com.imooc.springClass4.others.Bean5@77659b30 has been created
createBean5().toString() = com.imooc.springClass4.others.Bean5@77659b30
Bean5:com.imooc.springClass4.others.Bean5@456d6c1e has been created
createBean5().toString() = com.imooc.springClass4.others.Bean5@456d6c1e
Bean5:com.imooc.springClass4.others.Bean5@1e13529a has been created
createBean5().toString() = com.imooc.springClass4.others.Bean5@1e13529a
......
可以看到Bean6.printBean5()方法每次拿到的Bean5都是不同的实例
五、init-method和destroy-method
1. 如果需要在Bean实例化完成之后执行一些逻辑,可以有如下两种方法:
(1)使用init-method
(2)让Bean实现InitializingBean接口
2. 如果需要在Bean销毁之前执行一些逻辑,也有两种方法:
(1)使用destroy-method
(2)让Bean实现DisposableBean接口
例如:
public class Bean7 implements InitializingBean, DisposableBean { public Bean7() {
System.out.println(this.getClass().getSimpleName() + ":" + this.toString() + " has been created");
} public void onInit() {
System.out.println(this.getClass().getSimpleName() + ":" + "onInit");
} public void onDestroy() {
System.out.println(this.getClass().getSimpleName() + ":" + "onDestroy");
} public void afterPropertiesSet() throws Exception {
System.out.println(this.getClass().getSimpleName() + ":" + "afterPropertiesSet");
} public void destroy() throws Exception {
System.out.println(this.getClass().getSimpleName() + ":" + "destroy");
}
}
afterPropertiesSet()和destroy()是针对接口的实现。相应的xml配置:
<bean id="bean7" class="com.imooc.springClass4.others.Bean7" init-method="onInit" destroy-method="onDestroy"/>
测试:
@Test
public void testBean() throws Exception {
final AbstractApplicationContext context = new ClassPathXmlApplicationContext("spring.xml"); Bean7 bean7 = context.getBean("bean7", Bean7.class);
System.out.println("bean7 = " + bean7); context.close();
}
输出:
Bean7:com.imooc.springClass4.others.Bean7@57cf54e1 has been created
Bean7:afterPropertiesSet
Bean7:onInit
bean7 = com.imooc.springClass4.others.Bean7@57cf54e1
Bean7:destroy
Bean7:onDestroy
如果想设定当前xml中所有的bean都有相同的init-method和destroy-method,可通过设定default-init-method="????"、default-destroy-method="????"实现:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd"
default-init-method="onInit"
default-destroy-method="onDestroy"
>
</beans>
六、parent bean
可能存在如下场景:有很多Class继承于Class B,且Class B有很多的property,当我们需要实例化很多Class B子类的时候,如果这些子类从Class B继承的propertiy值基本相同,那么通过xml创建这些子类是一件很繁重的事情,并且会存在很多类似的重复性的代码出现。这种情况下,有如下解决办法,举例说明:
public class Bean8 { public Bean8() {
System.out.println(this.getClass().getSimpleName() + ":" + this.toString() + " has been created");
}
private String name;
private Integer age;
//get/set...
}
public class Bean8_1 extends Bean8{ public Bean8_1() {
System.out.println(this.getClass().getSimpleName() + ":" + this.toString() + " has been created");
}
private String address;
private Integer height;
//get/set/toString...
}
public class Bean8_2 extends Bean8{ public Bean8_2() {
System.out.println(this.getClass().getSimpleName() + ":" + this.toString() + " has been created");
}
private String email;
private Integer weight;
//get/set/toString...
}
<bean id="bean8" class="com.imooc.springClass4.others.Bean8" abstract="true">
<property name="name" value="zhang3"/>
<property name="age" value="33"/>
</bean>
<bean id="bean8_1" class="com.imooc.springClass4.others.Bean8_1" parent="bean8">
<property name="age" value="34"/>
<property name="address" value="JiangSu SuZhou"/>
<property name="height" value="155"/>
</bean>
<bean id="bean8_2" class="com.imooc.springClass4.others.Bean8_2" parent="bean8">
<property name="age" value="35"/>
<property name="email" value="123@abc.com"/>
<property name="weight" value="65"/>
</bean>
在xml中:
- 定义bean8,且设定abstracy=true,设定name和age的值
- 实例化bean8-1,且设定parent=bean8,重新设定age=34,设定address和height的值
- 实例化bean8-2,且设定parent=bean8,重新设定age=35,设定email和weight的值
测试:
@Test
public void testBean() throws Exception {
final AbstractApplicationContext context = new ClassPathXmlApplicationContext("spring.xml"); Bean8_1 bean8_1 = context.getBean("bean8_1", Bean8_1.class);
System.out.println("bean8_1 = " + bean8_1);
Bean8_2 bean8_2 = context.getBean("bean8_2", Bean8_2.class);
System.out.println("bean8_2 = " + bean8_2);
}
输出
bean8_1 = Bean8_1{address='JiangSu SuZhou', height=155', name=zhang3', age=34}
bean8_2 = Bean8_1{email='123@abc.com', weight=65', name=zhang3', age=35}
这样,我们就可以将Bean8子类的属性值统一在bean8中赋值进去,且由于bean8被标注的abstract所以并不会被创建。
另外,即使Bean8_1和Bean8_2没有继承于Bean8,但是Bean8_1和Bean8_2都有name和age属性,也可以用过类似的手段简化我们的代码,示例如下:
public class Bean9_1 { public Bean9_1() {
System.out.println(this.getClass().getSimpleName() + ":" + this.toString() + " has been created");
} private String name;
private Integer age;
private String address;
private Integer height; // get/set/toString......
}
public class Bean9_2{ public Bean9_2() {
System.out.println(this.getClass().getSimpleName() + ":" + this.toString() + " has been created");
} private String name;
private Integer age;
private String email;
private Integer weight; // get/get/toString...
}
<bean id="bean9" abstract="true">
<property name="name" value="zhang3"/>
<property name="age" value="33"/>
</bean>
<bean id="bean9_1" class="com.imooc.springClass4.others.Bean9_1" parent="bean9">
<property name="age" value="34"/>
<property name="address" value="JiangSu SuZhou"/>
<property name="height" value="155"/>
</bean>
<bean id="bean9_2" class="com.imooc.springClass4.others.Bean9_2" parent="bean9">
<property name="age" value="35"/>
<property name="email" value="123@abc.com"/>
<property name="weight" value="65"/>
</bean>
和之前bean8的区别就是,定义bean9的时候没有对应的Class
测试:
@Test
public void testBean() throws Exception {
final AbstractApplicationContext context = new ClassPathXmlApplicationContext("spring.xml"); Bean9_1 bean9_1 = context.getBean("bean9_1", Bean9_1.class);
System.out.println("bean9_1 = " + bean9_1);
Bean9_2 bean9_2 = context.getBean("bean9_2", Bean9_2.class);
System.out.println("bean9_2 = " + bean9_2);
}
输出
bean9_1 = Bean9_1{name='zhang3', age=34, address='JiangSu SuZhou', height=155}
bean9_2 = Bean9_2{name='zhang3', age=35, email='123@abc.com', weight=65}
Spring入门之四-------SpringIoC之其他知识点的更多相关文章
- Spring入门之五-------SpringIoC之通过注解实现
一.准备工作 创建一个Class注解@Configuration,如下例子: @Configuration // 该注解可理解为将当前class等同于一个xml文件 @ComponentScan(&q ...
- Spring入门之三-------SpringIoC之Scopes
一.singleton和prototype public class Bean1 { public Bean1() { System.out.println(this.getClass().getSi ...
- Spring入门篇总结:
本文是对慕课网上"搞定SSM开发"路径的系列课程的总结,详细的项目文档和课程总结放在github上了.点击查看 视频传送门:Spring入门篇 该门课程主要从Spring的Bean ...
- Spring入门5.事务管理机制
Spring入门5.事务管理机制 20131126 代码下载 : 链接: http://pan.baidu.com/s/1kYc6c 密码: 233t 回顾之前的知识,Spring 最为核心的两个部分 ...
- Spring入门4.AOP配置深入
Spring入门4.AOP配置深入 代码下载 链接: http://pan.baidu.com/s/11mYEO 密码: x7wa 前言: 之前学习AOP中的一些概念,包括连接点.切入点(pointc ...
- Spring入门2. IoC中装配Bean
Spring入门2. IoC中装配Bean 20131125 前言: 上一节学习了Spring在JavaProject中的配置,通过配置文件利用BeanFactory和ApplicationConte ...
- Spring入门1. IoC入门实例
Spring入门1. IoC入门实例 Reference:Java EE轻量级解决方案——S2SH 前言: 之前学习过关于Spring的一点知识,曾经因为配置出现问题,而总是被迫放弃学习这些框架技术, ...
- SSM(spring mvc+spring+mybatis)学习路径——1-1、spring入门篇
目录 1-1 Spring入门篇 专题一.IOC 接口及面向接口编程 什么是IOC Spring的Bean配置 Bean的初始化 Spring的常用注入方式 专题二.Bean Bean配置项 Bean ...
- Spring入门及IoC的概念
Spring入门 Spring是一个轻量级的Java开发框架,最早由Robd Johnson创建,目的为了解决企业级应用开发的业务逻辑层和其他各层的耦合问题,它是一个分层的JavaSE/EE轻量级开源 ...
随机推荐
- java.lang.ClassCastException: android.app.Application cannot be cast to
出这个异常的原因是在项目中添加了新lication类(public class Application extends lication)之后,没有在AndroidManifest.xml中添加该类的 ...
- Qtxlsx的使用
上一遍讲述了基于Qt5.9.8下编译Xtxlsx,本遍讲述基于Qt5.9.8下使用Qtxlsx 1.打开Qt Creator 4.8.2(Enterprise),创建工程,选择版本 2.在pro文件中 ...
- Shell Sort(希尔排序)
这个排序算法很厉害,我个人很喜欢这个算法,但算法的时间复杂度难计.算法对增量(这里也称作step(步长))的选择也需要注意,只记得个希尔增量的最坏情况为O(n^2).Hibbard增量的最坏情况为O( ...
- WebService介绍及C/C++访问
一.什么是WebService? Web 服务是一个软件接口,它描述了一组可以在网络上通过标准化的 XML 消息传递访问的操作.它使用基于 XML 语言的协议来描述要执行的操作或者要与另一个 Web ...
- Centos7 之 MariaDB(Mysql) root密码忘记的解决办法
MariaDB(Mysql) root密码忘记的解决办法 1.首先先关闭mariadb数据库的服务 # 关闭mariadb服务命令(mysql的话命令就是将mariadb换成mysql) [root@ ...
- gcc/g++/make/cmake/makefile/cmakelists的恩恩怨怨
以前在windows下用VS写代码,不管有多少个文件夹,有多少个文件,写完以后只需要一键就什么都搞定了.但是当移步linux下时,除非你使用图形界面,并且使用Qt creater这类的IDE时,才可以 ...
- 为何以及如何学Linux系统?
在当今的社会中,linux用处实在是太过广泛了.现在用在服务器和嵌入式上的Linux发行版本数不胜数,桌面上linux只占1%的比例,但这不代表linux比windows和mac 做得差,实际上桌面系 ...
- 第1节 kafka消息队列:11、kafka的数据不丢失机制,以及kafka-manager监控工具的使用;12、课程总结
12.kafka如何保证数据的不丢失 12.1生产者如何保证数据的不丢失 kafka的ack机制:在kafka发送数据的时候,每次发送消息都会有一个确认反馈机制,确保消息正常的能够被收到 如果是同步模 ...
- http请求常见的状态码
状态码是开发者需要了解的一项内容,日常开发中浏览器会返回给我们一些状态码,然后我们可以根据状态码所代表的含义进行问题解决. 1xx(临时响应) 表示临时响应并需要请求者继续执行操作的状态代码. 100 ...
- spring mvc ,spring boot 整合swagger
https://blog.csdn.net/qq_35992900/article/details/81274436