Spring Framework#
注:所有xml
省略spring
格式,需添加
IOC的XML配置详解#
配置bean
示例
xml
如下:
1
| <bean id="impl别名" class="impl的全类名"/>
|
java
如下:
1
2
3
4
5
6
7
8
9
10
| //这是被注入对象
class java {
public static void main(String[] args) {
//获取IOC容器
ApplicationContext ctx = new ClassPathXmlApplicationContext("xml文件名");
//获取bean
目标对象接口 对象名 = (目标对象接口类型强转) ctx.getBean("xml中的id属性值");
对象名.成员方法;
}
}
|
DI的XML配置详解#
xml
部分
1
2
3
4
5
6
| <!--给A注入B,A中包含B对象-->
<bean id="A别名" class="A全类名"/>
<bean id="B别名" class="B全类名">
<property name="A类中的B对象名" ref="A别名"/>
<!--将name值反过来也可以实现反向注入-->
</bean>
|
java
部分
1
2
3
4
5
6
| class java {
//提供set方法注入对象
public void set被注入对象名(对象类型 对象名) {
this.对象名 = 对象名;
}
}
|
bean
配置#
基本属性
属性名 | 属性作用 |
---|
id | 获取唯一的bean ,相当于别名,唯一 |
class | 全类名,bean 类型 |
name | 真正意义上的别名,可以用空格分割多个别名,影响getBean方法 |
scope | 可选prototype 非单例或者singleton 单例 |
bean
实例化#
构造方法
spring
默认调用空参构造方法进行对象实例化,通过反射调用内部构造方法
静态工厂
1
2
3
4
5
6
7
8
9
10
11
12
13
| class 对象Factory{
public static 对象接口 get对象(){
//工厂初始化行为代码
return new 对象impl();
}
}
class AppForInstance对象名{
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("application.xml");
对象接口 对象名 = applicationContext.getBean(对象接口名);
对象名.成员方法;
}
}
|
1
| <bean id="bean唯一标识" class="工厂全类名" factory-method="get对象的方法名"/>
|
示例工厂
旧版本:
1
2
3
4
5
6
7
8
9
10
11
12
| class 对象factory{
public 对象接口 get对象接口(){
return 对象impl();
}
}
class AppForInstance对象名{
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("application.xml");
对象接口 对象名 = applicationContext.getBean(对象接口名);
对象名.成员方法;
}
}
|
1
2
| <bean id="工厂唯一标识" class="工厂全类名"/>
<bean id="bean唯一标识" factory-method="get对象方法名" factory-bean="工厂唯一标识"/>
|
新版本:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| public class 对象FactoryBean implements FactoryBean<对象>{
//重写方法
public 对象 getObject() throws Exception{
//代替原始工厂中代替创建方法
return new 对象impl();
}
public Class<?> getObjectType(){
return 对象.class;
}
public boolean isSinglenton(){
return true;//是否开启单例
}
}
class AppForInstance对象名{
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("application.xml");
对象接口 对象名 = applicationContext.getBean(对象接口名);
对象名.成员方法;
}
}
|
1
| <bean id="对象标识" class="FactoryBean全类名"/>
|
bean
生命周期#
旧版本:
1
2
3
4
5
6
7
8
| public class 对象impl{
public void init(){
//初始化
}
public void destory(){
//销毁
}
}
|
1
| <bean id="唯一标识" class="全类名" init-method="init" destory-method="destory"/>
|
若要调用destory
方法需要在虚拟机关闭前执行容器关闭,有两种方式
- 直接调用
ApplicationContext
接口对象无法调用close
对象进行销毁,需要将对象换成 ClassPathXmlApplicationContext
接口对象并调用close
方法关闭容器从而实现close方法 - 创建完
ApplicationContext
对象后,调用对象.registerShutdownHook
成员方法注册关闭钩子,当虚拟机停止运行前会自动关闭容器并调用destory方法
新版本:
1
2
3
4
5
6
7
8
9
| public class 对象impl implements 对象接口,InitializingBean,DisposableBean{
//重写方法
public void afterPropertiesSet(){//这里的set是指set对象()方法之后
//init内容
}
public void destory(){
//destory内容
}
}
|
DI
详解#
多个对象注入方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| public class A{
public void doit(){
System.out.println();
}
}
public class B{
public void doit(){
System.out.println();
}
}
public class DItest{
private A a;
private B b;
void setA(A a){
this.a=a;
}
void setB(B b){
this.b=b;
}
}
|
1
2
3
4
5
6
| <bean id="A" class="A全类名"/>
<bean id="B" class="B全类名"/>
<bean id="DItest" class="DItest全类名">
<property name="a" ref="A"/>
<property name="b" ref="B"/>
</bean>
|
setter
注入
可选依赖使用setter
注入,灵活性强
1
2
3
4
5
6
7
8
9
10
| public class 对象impl{
private int i;
private String s;
public void setI(int i){
this.i = i;
}
public void setS(int s){
this.s = s;
}
}
|
1
2
3
4
| <bean id="唯一标识" class="全类名">
<property name="i" value="520"/>
<property name="s" value="你好"/>
</bean>
|
构造器注入
spring
强制依赖使用构造器进行依赖注入,setter
注入方式有概率造成null
错误
标准书写
对象注入
1
2
3
4
5
6
7
| public class B{
private A a;
public DItest(A a){
this.a=a;
//有参构造
}
}
|
1
2
3
4
5
6
| <!--将A注入到B-->
<bean id="A" class="A全类名">
<bean id="B" class="B全类名">
<constructor-arg name="B类构造器里的A参数" ref="A别名"/>
<!-- 注入多个bean就增加多个参数并且添加本条list-->
</bean>
|
变量注入
1
2
3
4
5
6
| public class DItest{
private String s;
public DItest(String s){
this.s=s;
}
}
|
1
2
3
| <bean id="DItest" class="全类名">
<constructor-arg name="构造器里的变量名" value="值"/>
</bean>
|
简便写法
- java部分不变,解决形参名耦合问题
1
2
3
4
| <bean id="DItest" class="全类名">
<constructor-arg type="int" value="值"/>
<!-- 用type属性指代参数类型,对应构造器变量-->
</bean>
|
- java部分不变,解决类型重复问题
1
2
3
4
| <bean id="DItest" class="全类名">
<constructor-arg index="0" value="值"/>
<!-- 从零开始,按照索引为构造器参数赋值-->
</bean>
|
自动装配#
按类型装配与按名称装配:
1
2
3
4
5
6
7
8
9
10
11
| public class A{
private B b;
public setB(B b){
this.b = b;
}
}
public java{
ApplicationContext context = new ClassPathXmlApplicationContext("application.properties");
A a = (A)context.getBean("a");
a.成员变量;
}
|
1
2
3
4
| <bean id="b" class="B全类名"/>
<bean id="a" class="A全类名" autowire="byType"/>
<!--按类型装配不可有多个符合条件的类-->
<bean id="a" class=""/>
|