您的位置:首页 > 编程语言 > Java开发

先码后看 spring配置bean的几种方式:xml直接配置、静态工厂、实例工厂、factory bean、注解 侵立删

2018-01-26 10:58 1111 查看
转自:http://blog.csdn.net/love___code/article/details/53167138

spring框架的核心在于“Ioc控制反转”“DI依赖注入”以及“AOP面向切面编程”,所以在实现这些核心是最基础的一步即为在ioc容器中配置bean标签,因为我们获取对象是通过获取bean 来获得的,所以配置好bean,要用对象时我们才能想用就拿.今天查看了一下资料,总结了以下三种方式来配置Bean.(自己定义成三种的,每个人按照自己不同标准可以划分很多种的

首先先看一下准备的示例类: 

1.一个Hello实体类,定义了name和person属性 

2.一个Person实体类定义了name属性 

(注:这里之所以提供两个实体类,是为了体现DI依赖注入的特性,这也是配置bean 中非常重要的一点) 

3.测试类–junit下面做的测试 

4.其他类–根据不同的方法来创建
//Hello类
package com.yc.spring;

import org.springframework.beans.factory.annotation.Autowired;

public class Hello {
private String name;
/* @Autowired//自动注入对象 */
private Person person;

public Hello() {
System.out.println("我是hello的构造方法");
}

public Hello(String name, Person person) {
super();
this.name = name;
this.person = person;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public Person getPerson() {
return person;
}

public void setPerson(Person person) {
this.person = person;
}

public void sayHello() {
System.out.println(String.format("%s 对 %s说你好帅!!!", name,
person.getname()));
}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
Person类,person作为Hello类的一个属性,所以Hello类依赖于Person类
package com.yc.spring;

public class Person {
String name;
@Override
public String toString() {
return "Person [name=" + name + "]";
}
public Person(String name) {
this.name = name;
}
public Person() {

}
public String getname() {
return name;
}
public void setname(String name) {
this.name = name;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//测试类
package com.yc.spring;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class HelloTest {
@Test
public void testHelloStaticFactory(){
ApplicationContext cxt=new ClassPathXmlApplicationContext("spring.xml");
System.out.println("==========");
Hello h01=(Hello) cxt.getBean("填写待测试的bean  id");
System.out.println(h01);
h01.sayHello();
//(取到hello对象并调用sayhello方法)

}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

第一种方式:通过编写xml方式直接配置bean; 

以下代码均在spring.xml的配置文件中编写:
<!-- xml方式配置bean  -->
<bean id="per6" class="com.yc.spring.Hello">
<property name="name" value="小满"></property>
<property name="person" ref="per6_1"></property>
</bean>
<!-- 创建Hello对象,通过ref引用依赖Person 类 -->
<bean id="per6_1" class="com.yc.spring.Person">
<property name="name" value="小钦"></property>
</bean>

运行结果:我是hello的构造方法
==========
com.yc.spring.Hello@1262d8c
小满 对 小钦说你好帅!!!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

第二种方式:通过工厂方式配置bean(工厂方式也就可以理解为,我们事先把我们要获获取的对象存放到工厂里,当我们要用的时候我们就直接通过加载工厂去获取我们想要的对象) 

工厂方式又分为:静态工厂和实例工厂 

2.1通过静态工厂方式配置bean(静态工厂,就是将我们的对象直接放在一个静态区里面,想用的时候我们可以直接调用就行)
//创建一个工厂类
package com.yc.spring;

import java.util.HashMap;
import java.util.Map;

public class HelloStaicFactory {
private static Map<Integer, Hello> map=new HashMap<Integer, Hello>();
static{
map.put(1,new Hello("小有",new Person("小瑶")));
//如果这里有多个对象要传入的话,就可以根据键来检索了
}//将我们的对象都存放到工厂里面去,而且都是静态的,可以随时调用

public static Hello getHello(int id){
return map.get(id);
}//对外提供获取接口,根据id获得对象
}

//一下是spring.xml中的代码
<!--  通过静态工厂方法来配置bean,注意不是配置静态工厂方法实例,而是配置bean实例
class属性:指向静态工厂方法的全类名
factory-method:指向静态工厂方法的名字
constructor-arg:如果静态工厂方法需要传入参数,则使用constructor-arg来配置参数
-->
<bean id="per1" class="com.yc.spring.HelloStaicFactory" factory-method="getHello">
<constructor-arg value="1"></constructor-arg>
</bean>

//测试结果:
==========
com.yc.spring.Hello@17864c4
小有 对 小瑶说你好帅!!!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

2.2通过实例工厂方式配置bean,实例工厂与静态工厂的区别在于一个是静态的,可直接调用的,一个是需要先实例化工厂,在获取工厂里面的对象的
package com.yc.spring;
import java.util.HashMap;
import java.util.Map;
public class HelloInstanceFactory {
private  Map<Integer, Hello> map;
public HelloInstanceFactory(){
map=new HashMap<Integer, Hello>();
map.put(4, new Hello("小桥",new Person("小跻")));
}
public Hello getHello(int id){
return map.get(id);
}
}

//一下是spring.xml文件代码
<!-- 2—2通过实例工厂方法来配置bean
factory-bean:指向实例工厂方法的bean
factory-method:指向实例工厂方法的名字
constructor-arg:如果实例工厂方法需要传入参数,则使用constructor-arg来配置参数
-->
<bean id="personFactory" class="com.yc.spring.HelloInstanceFactory"></bean>
<bean id="per4" factory-bean="personFactory" factory-method="getHello">
<constructor-arg value="4"></constructor-arg>
</bean>

运行结果:我是hello的构造方法
==========
com.yc.spring.Hello@5d53c3
小桥 对 小跻说你好帅!!!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

2.3通过实现factoryBean方法来配置bean–(小编是在不想分太多类了,就勉强加载工厂这里面了,望见谅)
package com.yc.spring;

import org.springframework.beans.factory.FactoryBean;
//通过实现FactoryBean 接口
public class HelloFactoryBean  implements FactoryBean<Hello>{
private int id;//讲道理,我现在还没理解这个id是干嘛用的,等博主知道之后再来修改,大家可自动忽略这里
public void setId(int id) {
this.id = id;
}
@Override
public Hello getObject() throws Exception {
return new Hello("小发",new Person("小荣"));
}
@Override
public Class<?> getObjectType() {
return Person.class;
}
@Override
public boolean isSingleton() {  //选择是否只调用一次构造函数,也就是多个对象的地址是否相同
return true;
}

}
//一下是spring.xml中的代码
<!--2-3  通过实现FactoryBean方法来配置bean
通过Factorybean来配置bean的实例
class:指向Factorybean的全类名
property:配置Factorybean的属性
但实际返回的实例却是Factorybean的getObject()方法返回的实例
-->
<bean id="per5" class="com.yc.spring.HelloFactoryBean">
<property name="id" value="1"></property>
</bean>
运行结果:
我是hello的构造方法
==========
com.yc.spring.Hello@1262d8c
小发 对 小荣说你好帅!!!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

第三种方式:通过注解方式(也是目前使用非常广泛的一种,至少我觉得比以上方便多了)
package com.yc.spring;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

@Component("hello")
//@component(把普通pojo实例化到spring容器中,相当于配置文件中的<bean id="hello" class="com.yc.spring.Hello"/>)
@Scope("prototype")//原型对象,默认为单例对象,选择会执行几次构造函数。这里选择是,每次获取新对象都会执行一次构造函数,对象地址都不同。
public class Hello {
private String name="小丹";
@Autowired//自动注入对象,这个注解就是spring可以自动帮你把bean里面引用的对象的bean,相当于ref的作用
private Person person;
public Hello() {
System.out.println("我是hello的构造方法");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}

public Person getPerson() {
return person;
}

public void setPerson(Person person) {
this.person = person;
}

public void sayHello(){
System.out.println(String.format("%s 对 %s说你好帅!!!",name,person.getname()));
}
}

package com.yc.spring;

import org.springframework.stereotype.Component;

@Component("person")//将person对象也加载到spring容器类
public class Person {
String name="小州";
@Override
public String toString() {
return "Person [name=" + name + "]";
}
public Person(String name) {
super();
this.name = name;
}
public Person() {

}

public String getname() {
return name;
}

public void setname(String name) {
this.name = name;
}

}
//以下为spring.xml中代码
<!-- bean就由spring容器创建好的对象 -->
<!-- 指定可以做为spring容器管理的对象的包 -->
<context:component-scan base-package="com.yc.spring"/>

运行结果:
我是hello的构造方法
com.yc.spring.Hello@d5ba3a
小丹 对 小州说你好帅!!!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74

以上即为配置bean的三种方式,个人感觉注解的最为轻松
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐