SpringBoot如何使用注解装配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,今天就分析到这里。
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- 腾讯云服务器操作系统TencentOS安装与体验
- 打卡群2刷题总结1004——无重复字符的最长子串
- 如何恢复故障KVM虚拟机qcow2磁盘镜像文件LVM分区中的数据
- 8000字 | 32 张图 | 一文搞懂事务+隔离级别+阻塞+死锁
- 闪回flashback
- 海贼王 One Piece,一起康康Vue版本号中的彩蛋
- MySQL 三万字精华总结 + 面试100 问,吊打面试官绰绰有余(收藏系列)
- Oracle数据结构
- 打卡群2刷题总结1003——搜索旋转排序数组
- Rman备份恢复和管理
- 重做日志和日志挖掘
- 『技术随手学』解决windows与ubuntu平台 CondaHTTPError: HTTP 000 CONNECTION FAILED 问题
- DevOps编程操练:用Jenkins流水线建立代码质量预警机制
- 『技术随手学』pip conda 替换清华源 Windows与Ubuntu通用
- 回滚段undo