文章目录
一、Spring配置类的实现
1、基本介绍
Spring Boot 推荐使用 java 配置完全代替 XML 配置,java 配置是通过 @Configration
和 @Bean
注解实现的,二者作用如下:
-
@Configration
注解:声明当前类是一个配置类,相当于 Spring 中的一个 XML 文件 -
@Bean
注解:作用在方法上,声明当前方法的返回值是一个 Bean
下面是最简单的一个示例
@Configuration
public class UserConfig {
@Bean
public String hello(){
return "hello world";
}
}
/**==============调用==============*/
@RestController
public class UserController {
@Autowired
String hello;
@GetMapping("/hello")
public String hello(){
return hello;
}
}
2、@Bean 注解详解
2.1 使用说明
-
@Bean
注解作用在方法上 -
@Bean
指示一个方法返回一个 Spring 容器管理的 Bean -
@Bean
方法名与返回类名一致,首字母小写 -
@Bean
一般和@Component
或者@Configuration
一起使用 -
@Bean
注解默认作用域为单例 singleton 作用域,可通过@Scope("prototype")
设置为原型作用域
2.2 Bean名称
1、默认情况下 Bean 名称就是方法名,比如下面 Bean 名称便是 myBean
@Bean
public MyBean myBean() {
return new MyBean();
}
2、 @Bean 注解支持设置别名。比如下面除了主名称 myBean 外,还有个别名 myBean1(两个都可以使用)
@Bean("myBean1")
public MyBean myBean() {
return new MyBean();
}
3、@Bean 注解可以接受一个 String 数组设置多个别名。比如下面除了主名称 myBean 外,还有别名 myBean1、myBean2(三个都可以使用)
@Bean({"myBean1", "myBean2"})
public MyBean myBean() {
return new MyBean();
}
2.3 @Bean 与其他注解一起使用
@Bean 注解常常与 @Scope、@Lazy,@DependsOn 和 @link Primary
注解一起使用:
-
@Profile
注解:为在不同环境下使用不同的配置提供了支持,如开发环境和生产环境的数据库配置是不同的 -
@Scope
注解:将 Bean 的作用域从单例改变为指定的作用域 -
@Lazy
注解:只有在默认单例作用域的情况下才有实际效果 -
@DependsOn
注解:表示在当前 Bean 创建之前需要先创建特定的其他 Bean
// @Bean(initMethod="init", destroyMethod="destroy") 可以调用初始化和销毁的方法
@Bean
// @Scope 注解将其改成 prototype 原型模式(每次获取 Bean 的时候会有一个新的实例)
@Scope("prototype")
public MyBean myBean() {
return new MyBean();
}
3、@Configration 注解详解
3.1 使用说明
-
@Configration
注解作用在类、接口(包含注解)上 -
@Configuration
用于定义配置类,可替换 xml 配置文件 -
@Configration
注解类中可以声明一个或多个 @Bean 方法 -
@Configration
注解作用的类不能是 final 类型 -
嵌套的
@Configration
类必须是 static 的
@SpringBootApplication
public class SpringBeanApplication {
public static void main(String[] args) {
ConfigurableApplicationContext context
= SpringApplication.run(SpringBeanApplication.class, args);
String myBean = (String) context.getBean("hello");
System.out.println(myBean);
}
}
3.2 @Bean与@Condition的组合
二、Bean注入的一些总结
1、多Bean注入
1.1 简介
@Resource
默认是按照名字注入,@Autowired
默认是按照类型注入,当一个容器内只有一个名字或者类型时,直接走默认就可以,Spring会自动帮我们注入;同时当只;有一个bean时,变量名取任何合法名字都可以。
但是当有多个相同类型的bean时,变量名必须根据注入Bean类名字获取,或者使用@Qualifier
注解指定某个Bean
1.2 代码详解
创建User类
public class User {
private String age;
private String name;
public User(String age, String name) {
this.age = age;
this.name = name;
}
@Override
public String toString() {
return "User{" +
"age='" + age + '\'' +
", name='" + name + '\'' +
'}';
}
}
创建config类,bean注入
@Configuration
public class UserConfig {
@Bean
public User user(){
User user = new User("18", "shawn");
return user;
}
@Bean
public User user1(){
User user = new User("19", "shawn1");
return user;
}
@Bean
public User user2(){
User user = new User("20", "shawn2");
return user;
}
}
使用
@RestController
public class UserController {
// 默认按照类型或者注入,下面两种都可以,当只有一个bean时,变量名取任何合法名字都可以
//@Resource
@Autowired
User user;
// Resource指定
@Resource(name = "user1")
User user11;
// 指定
@Autowired
@Qualifier(value = "user2")
User user22;
@GetMapping("/hello")
public void hello(){
System.out.println(user11);
}
}
2、Spring容器有参与无参构造
-
一般一个类他会自带一个默认的无参构造方法,如果你在其中写入了有参构造,在没有重新写入无参构造的情况下,该无参构造方法就不存在了
-
在使用spring框架时,在使用一个类的时候,spring容器会自动对该类进行实例化,但是该类必须时无参构造的,相当于spring的默认设置
-
如果在使用spring框架时,实体类的初始化方法是有参构造,那么需要在配置文件中进行配置(即.xml文件)或者注入相应的bean之后spring容器才能对该类进行实例化,否则会报错
-
当一个类存在有参和无参构造函数时,默认为无参,如果要执行有参构造,可以在构造函数上加
@Autowired
注解
@Configuration
public class UserConfig {
@Bean
public User user(){
User user = new User("18", "shawn");
return user;
}
}
/**=====================分割线==============*/
@Service
public class UserService {
private User user;
// 默认无参
public UserService(){
System.out.println("UserService空构造函数");
}
//@Autowired 会执行有参,多个bean的话注意对应方法名
@Autowired
public UserService(User user){
this.user=user;
System.out.println("UserService非空构造函数"+ user);
}
public void getUser(){
System.out.println("获取到的User为"+user);
}
}
3、@Bean 与 @Component
3.1 简介
当@Bean 与 @Component 同时作用同一个类时,Spring容器种到底有几个 对象
@Configuration
public class UserConfig {
@Bean
public UserService userService(){
return new UserService();
}
}
/**==========================================*/
@Service
public class UserService {
private User user;
// 默认无参
public UserService(){
System.out.println("UserService空构造函数");
}
@Autowired
public UserService(User user){
this.user=user;
System.out.println("UserService非空构造函数"+ user);
}
public void getUser(){
System.out.println("获取到的User为"+user);
}
}
3.2 解释说明
@Configuration
包含了 @Component
,在Spring扫描过程中,@Configuration+@Bean
方式会覆盖先创建的@Service
的Bean
但在 Spring 5.1.2.RELEASE (Spring Boot 则是 2.1.0.RELEASE )后,新增了配置项allowBeanDefinitionOverriding 来控制是否允许 BeanDefinition 覆盖,默认情况下是不允许的。我们可以在配置文件中配置:spring.main.allow-bean-definition-overriding=true ,允许 BeanDefinition 覆盖