(6)装配Bean配置(注解)

# 通过注解装配Bean

## 使用@Component 装配Bean

- 定义一个`POJO`:

```

@Component(value = "role")

public class Role {

@Value("1")

private Long id;

@Value("role_name_1")

private String roleName;

@Value("role_note_1")

private String note;

/*** setter and getter ***/

}

```

- **注解`@Component`代表Spring IoC会把这个类扫描生成`Bean`实例**

> - `value`

属性代表这个类在Spring中的`id` ,这就相当于XML方式定义的`Bean`的`id`

>> - 可以简写成`@Component("role")`

>> - 直接写成`@Component`,默认类名首字母小写为`id`

- 现在有了这个类,但是还不能进行测试,因为Spring IoC 并不知道需要去哪里扫描对象,这个时候可以使用一个`Java Config `来去告诉它

```

package com.ssm.chapter10.annotation.pojo;

import org.springframework.context.annotation.ComponentScan;

@ComponentScan

public class PojoConfig {

}

```

- **包名和POJO一致**

- **`@ComponentScan`代表进行扫描,默认是扫描当前包的路径, `POJO`的包名和它保持一致才能扫描**

---

- 然后就可以通过`Spring`定义好的Spring IoC容器的

实现类`AnnotationConfigApplicationContext`去生成IoC容器(一般放在专门的`config`文件夹中)

```

public class AnnotationMain {

    public static void main(String[] args){

        ApplicationContext context =  new AnnotationConfigApplicationContext(PojoConfig.class);

        Role role = context.getBean(Role.class);

        System.err.println(role.getId();

```

---

- 扫描多个包

```

//1

@ComponentScan(basePackages = {"com.ssm.chapter10.annotation.pojo",

"com.ssm.chapter10.annotation.service"})

//2

@ComponentScan(basePackages = {"com.ssm.chapter10.annotation.pojo",

"com.ssm.chapter10.annotation.service"},

basePackageClasses = {Role.class, RoleServiceImpl.class})

```

- 难以注入对象

- 配置复杂

## 自动装配 @Autowired(推荐)

```

@Component

public class RoleController {

@Autowired

private RoleService roleService = null;

//同时也可以通过方法配置自动装配

@Autowired

public void setRole(Role role){

    this.role = role;

}

}

```

- IoC 容器有时候会寻找失败,在默认的情况下寻找失败它就会抛出异常,可以通过`@Autowired(required =false)`配置

- `@Autowired`是按**类型**,在存在多个相同类型的类时装配会失败

### 解决@Autowired歧义性

为了消除歧义性, `Spring` 提供了两个注解`@Primary` 和`@Qualifier`

- 注解`@Primary`代表首要的,配置在需要注入的类上,它是告诉Spring IoC 容器,请优先使用该类注入

- 注解`Qualifier`是通过按名称注入,常和`@component`等配合,例如

```

@Component("roleService3")

public class RoleServiceImpl3 implements RoleService {}

```

```

@Component

public class RoleController {

@Autowired

@Qualifier("roleService3")

private RoleService roleService = null;

}

```

## 使用@Bean 装配Bean

以上都是通过`@Component`装配`Bean` ,但是`@Component` 只能注解在类上,不能注解到方法上,这个时候我们可以使用`@Bean`来解决

- 比如我们需要使用DBCP 数据源, 这个时候要引入关于它的包

```

    @Bean(name = "dataSource")

public DataSource getDataSource(

Properties props = new Properties();

props.setProperty("driver", ....);

props.setProperty("url", ....);

props.setProperty("username", ....);

props.setProperty("password", ....);

DataSource dataSource = null;

try {

dataSource = BasicDataSourceFactory.createDataSource(props);

} catch (Exception e) {

e.printStackTrace();

}

return dataSource;

}

```

**`@Bean`包含四个配置项**

> - `name`:是一个字符串数组,允许配置多个BeanName

> - `autowire`:标志是否是一个引用的Bean对象,默认值是`Autowire.NO`

> - `initMethod`:自定义初始化方法

> - `destroyMethod`:自定义销毁方法

```

@Bean(name="juiceMaker2", initMethod="init", destroyMethod="myDestroy")

public JuiceMaker2 initJuiceMaker2() {

JuiceMaker2 juiceMaker2 = new JuiceMaker2();

juiceMaker2.setBeverageShop("贡茶");

Source source = new Source();

source.setFruit("橙子");

source.setSize("大杯");

source.setSugar("少糖");

    juiceMaker2.setSource(source);

return juiceMaker2;

}

```

# XML与注解混用

在现实中,使用XML或者注解各有道理,建议在自己的工程中所开发的类尽量使用注解方式,因为使用它并不困难, 甚至可以说

更为简单,而对于引入第三方包或者服务的类,尽量使用XML 方式,这样的好处是可以尽量对三方包或者服务的细节减少理解,也更加清晰和明朗。

- 例如:

配置数据源`spring-datasource.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-4.0.xsd">

<bean id="dataSource1" class="org.apache.commons.dbcp.BasicDataSource">

<property name="driverClassName" value="com.mysql.jdbc.Driver" />

<property name="url" value="jdbc:mysql://localhost:3306/chapter10" />

<property name="username" value="root" />

<property name="password" value="123456" />

</bean>

</beans>

```

- 在`xxxxx-config.java`中导入数据源

```

@ImportResource({"classpath:spring-dataSource.xml"})

public class ApplicationConfig {

.....

}

```

- 最后就可以注入

```

@Autowired

DataSource dataSource = null;

```

**在有多个config文件或者多个xml文件时可以进行导入:**

```

@Import({ApplicationConfig2.class,ApplicationConfig3.class})

public class ApplicationConfig {

.....

}

```

以及

```

<import resource = "spring-config.xml"/>

```

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。