JavaEE笔记(三):Bean的装配方式
Bean 的装配可以理解为依赖关系注入, Bean 的装配方式即 Bean 依赖注入的方式
Bean的三种装配方式
-
基于 XML 的装配
- 设值注入( Setter Injection )
- 构造注入( Constructor Injection )
-
基于注解( Annotation )的装配
-
自动装配
基于 XML 的装配方式:<bean>标签就是告诉spring怎么获取这个bean,各种<ref>就是手动的配置bean之间的关系
1. 常用Spring注解
1.1 两类注解
① 注册Bean
@Component(可作用在任何层) , @Repository(用于数据访问层), @ Controller(用于控制层) , @Service(用于业务层), @Configration 这些注解都是把你要实例化的对象转化成一个Bean,放在IOC容器中
② 使用Bean
就是把已经在xml文件中配置好的Bean拿来用,完成属性、方法的组装
可以通过byTYPE(@Autowired)、byNAME(@Resource)的方式获取Bean
@Autowired
-
作用:@Autowired表示被修饰的类需要注入对象,spring会扫描所有被@Autowired标注的类,然后根据类型在IOC容器中找到匹配的类注入
-
默认按类型注入 (by TYPE)
-
如果要使用byNAME名称装配,配合**@Qualifier**注解
@Autowired @Qualifier(value=""user2"")
与@Resource(name="user2")
是等价的
@Resource
- 默认按名称进行注入 (by NAME)
@Resource(name="user2")
@Autowired
@Qualifier("user2")
User u;
1.2 配置文件值注入
@Value
- 字面量
- # {spel}
- ${key}从环境变量配置文件中取值
@PropertySource
-
@PropertySource: 加载指定的配置文件
-
@PropertySource("classpath:my.properties")
@ConfigurationProperties
- 批量注入配置文件中的属性
- 默认加载配置文件application.properties(yml)
2. 装配Bean方式
2.1 @Component+@Autowired
- @Component:标识Bean,可被自动扫描发现
- @Autowired:自动装配,查找容器中满足条件的Bean,注入
- @Value:属性注入
- 在自动配置的方式中,使用@Component去告诉Spring,我是一个Bean,你要来管理我,然后使用@AutoWired注解去装配Bean(所谓装配,就是管理对象直接的协作关系)
@Component
- 标明哪个类被扫描进入Spring IOC容器
- 作用:把普通pojo实例化到spring容器中,相当于配置文件中的
<bean id="" class=""/>
- @Component就是告诉spring,我是pojo类,把我注册到容器中吧,spring会自动提取相关信息。那么我们就不用写麻烦的xml配置文件了
- 也可以写成
@Component("User")
,其中配置的"User"则是作为Bean的名称
//路径:src\main\java\com\entity\User.java
package com.entity;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class User {
@Value("xxx-component")
String name="xxx-2";
int age;
@Override
public String toString() {
return super.toString()+"User{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
2.2 @Configuration + @Bean + @Autowired
- 在JavaConfig中,@Configuration其实就是告诉Spring,Spring容器要怎么配置(怎么去注册Bean,怎么去处理Bean之间的关系(装配))
- @Bean的意思就是,我要获取这个Bean的时候,你Spring要按照这种方式去帮我获取到这个Bean
@Configuration
-
告诉Spring这是一个配置类,也就是配置文件
-
声明一个类作为配置类,代替xml文件
-
@Configuration==beans.xml
@Bean
-
给容器中注册一个Bean
-
类型为返回值的类型,id默认是用方法名作为id。
-
@Bean
等价于<bean></bean>
@Bean(value = "beanLife",initMethod = "init", destroyMethod = "destroy")
等价于
<bean id="person" class="com.java.model.Person" init-method="init" destroy-method="destroy"></bean>
//路径:src\main\java\com\config\MyConfig.java
package com.config;
import com.entity.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MyConfig {
@Bean(name="user2")
public User initUser()
{
User u=new User();
u.setName("xxx");
u.setAge(99);
return u;
}
//可以产生多个同类型但不同名的Bean
@Bean(name="user3")
public User initUser2()
{
User u=new User();
u.setName("yyy");
u.setAge(888);
return u;
}
}
测试类中的代码
多个同类型但不同名的Bean,采用按byNAME的方式获取Bean
//二者皆可
@Resource(name="user2")
@Autowired @Qualifier("user2")
User u;
2.3 @Component + @ConfigurationProperties + @Autowired
Springboot在启动时并不会加载其他配置文件,它只加载默认的配置文件application.properties(yml),因此,将配置信息添加到这里,通过前缀进行区分,进行引用
//路径:src\main\resources\application.properties
book.name=xxx\u4E2D\u6587
book.price=123
book.author="yy","xx"
@ConfigurationProperties(prefix = “book”) //这里需要定义出在application文件中定义的属性值的前缀信息
//路径:src\main\java\com\entity\Book.java
package com.entity;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
import java.util.Arrays;
@Component
@ConfigurationProperties(prefix = "book")
public class Book {
String name;
double price;
String[] author;
public String[] getAuthor() {
return author;
}
public void setAuthor(String[] author) {
this.author = author;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
@Override
public String toString() {
return "Book{" +
"name='" + name + '\'' +
", price=" + price +
", author=" + Arrays.toString(author) +
'}';
}
}
3. @Configuration与@Component的差别
都是注解在类上的
@Configuration
- 是随容器启动开始加载的,始终存在的单例模式
- 如果类是@configuration标注的话,每次调用返回的是同一个实体Bean
- @Configuration标注下的@Bean调用函数使用都是代理对象,获取的都是从IOC容器里获取的bean,因此都是同一个
- @Configuration注解,一般注解在类里面有@Value注解的成员变量或@Bean注解的方法
- 类中的方法成员变量是@Value注解,方法上的注解是**@Bean**
拓展:单例模式
- 单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一
- 这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式
- 这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建
- 这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。
注意:
- 1、单例类只能有一个实例
- 2、单例类必须自己创建自己的唯一实例
- 3、单例类必须给所有其他对象提供这一实例
@Component
- 是使用一次即实例化一次
- 如果类是@Component标注的,每次调用获取的都是新的实体
- @Component标注下的@Bean下只是普通的函数方法调用
- @Component注解的范围广,所有类都可以进行注解
- @Component包含了@Configuration的所用注解
4. @Component与@Bean的差别
- 都是注册Bean到Spring容器中
- 不能同时使用@Component与@Bean,@Bean一般与@Configuration一起使用
@Component
- 作用就相当于 XML配置
- @Component(@Controller、@Service、@Repository)通常是通过类路径扫描来自动侦测以及自动装配到Spring容器中
- 在想要将第三方库中的组件装配到你的应用中的这种情况下,是没有办法在它的类上添加@Component和@Autowired注解的,因此就不能使用自动化装配的方案(可以使用XML装配)
@Bean
- @Bean注解的方法:会实例化、配置并初始化一个新的对象,这个对象会由spring IoC 容器管理
- 需要在配置类中使用,即类上需要加上@Configuration注解
- @Bean注解通常是我们在标有该注解的方法中定义产生这个bean的逻辑
- 在想要将第三方库中的组件装配到你的应用中的这种情况下,可以使用@Bean
5. @Configuration 与@Bean的差别
@Configuration
- 相当于Spring.xml中配置文件的<beans>标签
- 用在类上
@bean
-
相当于Spring.xml中配置文件的<bean>标签
-
后者用在方法上