Spring中几种配置Bean的方式分别是:
基于XML的配置方式
基于注解的配置方式
基于Java类的配置方式

基于 XML 配置方式

XML 配置方式应该是比较麻烦也比较简单的一种方式了。所以关于 XML 的配置,我这里就直接列出几个栗子,直接看就好了。

1
2
3
4
5
<bean id="juiceProduce" class="com.spring.bean.JuiceProduce">
<property name="water" value="大杯" />
<property name="fruit" value="橙汁" />
<property name="sugar" value="三分糖"/>
</bean>

这里这样配置,是要求我们的 Bean 类里面有我们的 set 方法的。

1
2
3
4
5
6
7
8
9
10
11
public void setWater(String water) {
this.water = water;
}

public void setFruit(String fruit) {
this.fruit = fruit;
}

public void setSugar(String sugar) {
this.sugar = sugar;
}
1
2
3
4
5
6
7
<!-- 若一个 bean 有多个构造器, 如何通过构造器来为 bean 的属性赋值 -->
<!-- 可以根据 index 和 value 进行更加精确的定位. (了解) -->
<bean id="car" class="com.spring.bean.Car">
<constructor-arg value="KuGa" index="1"/>
<constructor-arg value="ChangAnFord" index="0"/>
<constructor-arg value="250000" type="float"/>
</bean>

这里的要求是,在我们的 Bean 类中,要求有这三个参数的构造器,constructor-arg 是我们构造器参数列表,value 代表我们的参数值,index 表示当前参数是哪个位置的,type 表示参数的类型是什么。 index 和 type 是可以混合使用的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public Car(String company, String brand, int maxSpeed) {
this.company = company;
this.brand = brand;
this.maxSpeed = maxSpeed;
}

public Car(String company, String brand, float price) {
this.company = company;
this.brand = brand;
this.price = price;
}

public Car(String company, String brand, int maxSpeed, float price) {
this.company = company;
this.brand = brand;
this.maxSpeed = maxSpeed;
this.price = price;
}
1
2
3
4
5
6
7
8
9
10
11
<!-- 装配集合属性 -->
<bean id="user" class="com.atguigu.spring.helloworld.User">
<property name="userName" value="Jack"></property>
<property name="cars">
<!-- 使用 list 元素来装配集合属性 -->
<list>
<ref bean="car"/>
<ref bean="car2"/>
</list>
</property>
</bean>

这里我们看到,一个人可能不止一辆车。所以多车是一个集合的形式,这个集合就对应着我们的 一个List .

1
2
3
4
5
6
7
public List<Car> getCars() {
return cars;
}

public void setCars(List<Car> cars) {
this.cars = cars;
}

可以看到,这里我们的list 相当于内置的,现在我们可以把这个list放出来

1
2
3
4
5
<!-- 声明集合类型的 bean -->
<util:list id="cars">
<ref bean="car"/>
<ref bean="car2"/>
</util:list>

拿出来之后,对于上面的配置就可以改成

1
2
3
4
5
<!-- 装配集合属性 -->
<bean id="user" class="com.atguigu.spring.helloworld.User">
<property name="userName" value="Jack"></property>
<property name="cars" ref="cars"></property>
</bean>

我们也可以设置内部 Bean , 对于内部 Bean ,类似于匿名内部类对象,不能被外来的 bean 引用,也没有设置 id 属性。

同样,我们的 bean 也可以被继承,使用 parent 来完成继承关系。

1
<bean id="user-child" parent="user" p:userName="Bob"></bean>

如果说,我们的一个 配置文件里面有许多不同类型的 bean 配置,放在一起会维护比较麻烦。所以我们会把相关的 bean 放在同一个 xml 文件里面,然后把 xml 作为资源导入到我们总的 xml 里面去。

1
2
3
4
5
6
7
<beans>//Bean定义的开始和结束
<import resource=“resource1.xml” />//导入其他配置文件Bean的定义
<import resource=“resource2.xml” />
<bean id=“bean1” class=“***”></bean>
<bean name=“bean2” class=“***”></bean>
<alias alias=“bean3” name=“bean2” />//alias用于定义Bean的别名
</beans>

基于注解的方式

组件类注解

注解的方式应该是最简单的一种的方式了。我们可以来看看我们常常用到的几个注解:

@Component
基本注解,是Spring容器中的基本注解,表示一个容器的组件(bean),可以用做任何一个层次。

1
2
3
4
@Component("user")
public class User {
// nothing
}

这里的 @Component("book") 相当于我们的:<bean id="userTome" class="com.spring.bean.User">

@Resposity
标注的是一个数据访问层(DAO)层;

1
2
3
4
5
6
7
8
9
10
11
public interface UserDAO {
List<User> getAllUsers();
}

@Repository
public class UserDaoImpl implements UserDAO {
@Override
public List<User> getAllUsers() {
return null;
}
}

@Service
标注一个业务逻辑层;

1
2
3
4
5
6
7
8
9
public class UserService {

@Autowired
private UserDAO userDAO ;

public void doSomething(){
// nothing
}
}

@Controller
标注一个控件层。

1
2
3
4
5
6
7
8
9
10
@Controller
public class UserController {

@Autowired
private UserService userService ;

public void doNothing(){
// the code yourself
}
}

以上几个注解实质是属于同一类注解,用法相同。功能相同,区别是标识的组件不同。后三者都是在 Component 的基础上被标注的。也就是说,@Component 可以替代后面的。我们加了注解后,最好在配置文件中让Spring搜索指定路径

1
2
<!-- 自动扫描指定包及其子包下的所有Bean类 -->
<context:component-scan base-package="com.spring.*"/>

Bean 的生命周期注解

在XML文件中使用init-methoddestory-method 属性,指定初始化之后和回调之前的回调方法。这两个属性的取值是bean中相应的初始化和销毁方法的名称。方法名称任意,但是方法不能有参数。

1
2
3
4
<bean id="userService" class="com.spring.serve.UserService"
init-method="init"
destroy-method="destroy">
</bean>

我们要是走注解的形式就是这样的。

1
2
3
4
5
6
7
8
9
10
11
public class UserService {
@Autowired
private UserDAO userDAO ;
public void doSomething(){
// nothing
}
@PostConstruct
public void init(){}
@PreDestroy
public void destroy(){}
}

这里,我们需要在 配置文件中加入(具体为啥,我也不是很清楚):

1
<context:annotation-config/>

自动装配

@Autowired
这是自动装配的注解,前面已经用过了就不在用了。官方给出的说法是:Marks a constructor, field, setter method or config method as to be autowired by Spring’s dependency injection facilities. 我们可以通过这个注解给构造器,字段,set 方法或者是配置方法进行注入。

这里,如果说我们的Spring中存在多个所需类型的Bean , 我们使用这个注解来区分:

1
2
3
4
5
public class UserService{
@Autowired
@Qualifier("userDao")
private UserDao userDao;
}

基于Java的方式

我们使用Java来配置元数据的时候呀,其实就是通过 Java类来定义Speing 配置元数据。这里,我们需要用到的几个配置:

*@Configuration标注配置类的

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
@Configuration("swaggerConfig") // 这里的是当前bean的名字
@Configuration
public class SwaggerConfig {
// 接口版本号
private final String version = "1.0";
// 接口大标题
private final String title = "任务调度框架API接口";
// 具体的描述
private final String description = "任务调度框架Azkaban API接口调用测试";
// 服务说明url
private final String termsOfServiceUrl = "http://www.kingeid.com";
// licence
private final String license = "MIT";
// licnce url
private final String licenseUrl = "https://mit-license.org/";
// 接口作者联系方式
private final Contact contact = new Contact("SunYang", "https://github.com/sun-iot/workflow-azkaban", "sunyang.iot@gmail.com");

@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("com.ci123.workflow.azkaban.controller"))
.paths(PathSelectors.any())
.build();
}

private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("任务调度框架Azkaban API接口")
.description("简单优雅的restfun风格")
.termsOfServiceUrl("https://github.com/sun-iot/workflow-azkaban")
.version("1.0")
.contact(contact)
.build();
}
}

我们这里的 @Bean 配置,其实是:

1
2
3
4
@Bean(name={},
autowire=Autowire.NO,
initMethod="",
destroyMethod="")

具体怎么配置看具体需求。这里,我们如果需要引入我们的xml 的配置文件,就这样写:

1
2
3
@Configuration
@ImportResource("classpath:com/jike/***/appCtx.xml")
public class SwaggerConfig() {}

如果我们要引入其他的配置类,就这样写:

1
@Import(JavaOtherConfig.class)

我在网上找到了一个不同配置之间的总结:
2-1