Bean相关注解的装配和解析

Bean相关注解的装配和解析

在日常开发中,项目中大量的Bean的装配。今天就来聊聊如何使用注解装配Bean。这里与其说是SpringBoot装配Bean还是不如说是Spring注解来装配Bean。

装配Bean的方式主要有以下两种方式:

通过Java配置文件@Bean的方式来定义Bean

通过注解扫描的方式@Component和@ComponentScan

一、使用@Bean的方式
首先写一个非常普通的实体类MyBean

public class MyBean {
public String getName() {
return “使用@Bean方式”;
}
}
然后定义一个MyBeanConfig类,在类上添加注解@Configuration,

@Configuration该注解代表是一个 Java 配置文件 , Spring会根据它来生成 IoC 容器去装配 Bean。

@Bean 代表将 configBean方法返回的 POJO 装配到 IoC 容器中, name为Bean 的名称,如果没有配置它,则会将方法名称作为 Bean 的名称保存到 Spring IoC 容器中 。这里方法名称myBean就是MyBean保存在Spring IoC 容器中饿名称,如果在使用名称注入的时候就得使用myBean。否则会报错。

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MyBeanConfig {
@Bean
public MyBean configBean() {
return new MyBean();
}
}
看看@Bean源码会发现,其实除了上面说的方法名称作为Bean在Spring IOC 容器中的Bean名称外,还可以使用@Beam(“configBean”)的方式。

@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Bean {
@AliasFor(“name”)
String[] value() default {};

@AliasFor("value")
String[] name() default {};
//...省略

}
下面我们创建一个测试controller。

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

@RestController
public class MyController {
@Resource(name = “configBean”)
private MyBean configBean;

@GetMapping("/test/bean")
public String test(){
    return configBean.getName();
}

}
启动类

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
启动项目

测试工具使用IDEA的工具类里

访问:http://localhost:8080/test/bean

成功搞定。

用上面说的另外一种方式定义Beande 名称

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MyBeanConfig {
@Bean(“helloBean”)
public MyBean configBean() {
return new MyBean();
}
}
其他不动,再次启动启动类,就会报异常

所以得注入时候使用Bean名称也得跟着改(按照类型注入得另说,这里是演示Bean在Spring IOC中的名称)。

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

@RestController
public class MyController {
//这里把bean在Spring IOC中的名称修改成上面定义的helloBean名称
@Resource(name = “helloBean”)
private MyBean helloBean;

@GetMapping("/test/bean")
public String test(){
    return helloBean.getName();
}

}
正常启动

访问也正常

ok,使用@Bean的方式就这样轻松搞定。

二、使用@Component方式
创建一个类MyComponentBean

import org.springframework.stereotype.Component;

@Component
public class MyComponentBean {

public String getName(){
    return "使用@Component注解方式";
}

}
一样的,写一个controller类来测试,MyComponentController

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

@RestController
public class MyComponentController {

@Resource
private MyComponentBean myComponentBean;

@GetMapping("/test/component")
public String test(){
    return myComponentBean.getName();
}

}
启动启动类main方法(和上面一样)。然后访问返回

成功。注解@Component 表明这个类将被Spring IoC容器扫描装配,bean的名称为componentBean。如果不配置这个值 ,那IoC 容器就会把类名第一个字母作为小写,其他的不变作为 Bean 名称放入到 IoC 容器中。

在工作中,controller里我们通常会注入各种service类。比如:UserInfoService、OrderService等。这些service上基本上都会使用@Service,在service层又会注入各种Repository、Mapper、Dao等,然后这些类上基本都添加了注解@Repository来装配Bean。

进入org.springframework.stereotype目录下会发现

其实@Controllert、@Service、@Repository注解上都添加了注解@Component

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Controller {
@AliasFor(
annotation = Component.class
)
String value() default “”;
}

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Service {
@AliasFor(
annotation = Component.class
)
String value() default “”;
}

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Repository {
@AliasFor(
annotation = Component.class
)
String value() default “”;
}
也就是说,除了@Component注解以外,还可以使用上面这三个注解装配Bean。

@Controller 控制器(注入服务)

@Service 服务(注入dao)

@Repository dao(实现dao访问)

@Component (把普通pojo实例化到spring容器中,相当于配置文件中的

OK,使用@Component的方式就这样轻松搞定。

三、使用@ComponentScan方式
@ComponentScan是Spring的包扫描组件,作用在配置类上。使用方式为:

@ComponentScan(value=“com.example.demo”)

其常用属性介绍:

value:代表需要扫描的包,扫描包下的有注解@Controller、@Service、@Repository、@Component注解标注的类,将其注入IOC容器。

excludeFilters :是一个 Filter[]数组,作用是排除不需要扫描的包或者类。Filter[]数组里面需要@Filter指定过滤规则,@Filter的type属性表示过滤的规则;@Filter的classes属性是个数组,里面包含需要过滤的类。

includeFilters :是一个 Filter[]数组,作用是指定扫描的时候只需要包含哪些组件。用法与excludeFilters相同

useDefaultFilters:默认过滤规则选项,false时,可以自定义过滤规则

使用场景很多,比如说上文提到的启动类中的SpringBootApplication注解中就使用到了。

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
//使用@ComponentScan
@ComponentScan(excludeFilters = {
@Filter(type = FilterType.CUSTOM, classes = {TypeExcludeFilter.class}),
@Filter(type = FilterType.CUSTOM, classes = {AutoConfigurationExcludeFilter.class})}
)
public @interface SpringBootApplication {
@AliasFor(
annotation = EnableAutoConfiguration.class
)
Class<?>[] exclude() default {};

@AliasFor(
    annotation = EnableAutoConfiguration.class
)
String[] excludeName() default {};

@AliasFor(
    annotation = ComponentScan.class,
    attribute = "basePackages"
)
String[] scanBasePackages() default {};

@AliasFor(
    annotation = ComponentScan.class,
    attribute = "basePackageClasses"
)
Class<?>[] scanBasePackageClasses() default {};

}
ok,今天就分析到这里。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值