自动装配
@ComponentScan
用于配置Spring需要扫描的被组件注解注释的类所在的包。
@Component
用于标注一个普通的组件类,它没有明确的业务范围,只是通知Spring被此注解的类需要被纳入到Spring Bean容器中并进行管理。
@Autowired
Autowired用于自动装配,对于接口的实现类,可以使用该注解,消除get和set方法。
声明一个接口
public interface UserService {
void readyTest(String var);
}
单个实现类
新建一个类,实现该接口
import org.springframework.stereotype.Service;
@Service
public class UserServiceImpl implements UserService{
@Override
public void readyTest(String var) {
System.out.println("方法被调用,收到参数:"+var);
}
}
使用@Autowired注解,实现属性的自动装配
@SpringBootTest
class TestApplicationTests {
// 属性自动装配,可以省略get和set方法
// 此处的属性名称可以任意自定义,都会去找 UserService 接口的唯一实现类
@Autowired
UserService userServiceImpl;
@Test
void contextLoads() {
userServiceImpl.readyTest("Autowired");
}
}
多个实现类
我们新建一个实现类
import org.springframework.stereotype.Service;
@Service
public class UserServiceNewImpl implements UserService{
@Override
public void readyTest(String var) {
System.out.println("新方法被调用,收到参数:"+var);
}
}
当有多个实现类的情况下,会报错:无法自动装配。存在多个 'UserService' 类型的 Bean。
idea会自动识别此错误。
此时需要显式指定实现类:
@SpringBootTest
class TestApplicationTests {
@Autowired
UserService userServiceNewImpl;// 参数名称为类名
@Test
void contextLoads() {
userServiceNewImpl.readyTest("Autowired");
}
}
或者配合@Qualifier注解使用:
@SpringBootTest
class TestApplicationTests {
@Autowired
@Qualifier("userServiceNewImpl") // 指定实现类
UserService userService;
@Test
void contextLoads() {
userService.readyTest("Autowired");
}
}
@Resource
@Resource 和 @Autowired 一样,是用来实现依赖注入的。
声明一个接口
public interface UserService {
void readyTest(String var);
}
单个实现类
新建一个类,实现该接口
import org.springframework.stereotype.Service;
@Service
public class UserServiceImpl implements UserService{
@Override
public void readyTest(String var) {
System.out.println("方法被调用,收到参数:"+var);
}
}
使用@Resource 注解,实现属性的自动装配
@SpringBootTest
class TestApplicationTests {
@Resource
UserService userService;
@Test
void contextLoads() {
userService.readyTest("Resource");
}
}
当单个实现类,对应不同的bean时,也可以使用name属性指定具体的bean
@SpringBootTest
class TestApplicationTests {
@Resource(name="student")
private SayInterface student;
@Resource(name="teacher")
private SayInterface teacher;
@Test
void contextLoads() {
student.say();
teacher.say();
}
}
@Configuration
public class HumanConfig {
@Bean(name = "student",initMethod = "init")
public Human getStudent() {
Human student = new Human();
student.setName("Teacher");
return student;
}
@Bean(name = "teacher",destroyMethod = "destroy")
public Human getTeacher() {
Human teacher = new Human();
teacher.setName("Student");
return teacher;
}
}
多个实现类
我们新建一个实现类
import org.springframework.stereotype.Service;
@Service
public class UserServiceNewImpl implements UserService{
@Override
public void readyTest(String var) {
System.out.println("新方法被调用,收到参数:"+var);
}
}
当有多个实现类的情况下,会报错:org.springframework.beans.factory.BeanCreationException: Error creating bean with name
需要区分的是,idea不会自动识别此错误,在运行时才会报错。
解决方法就是手动指定@Resource的name属性:
@SpringBootTest
class TestApplicationTests {
@Resource(name = "userServiceNewImpl")
UserService userService;
@Test
void contextLoads() {
userService.readyTest("Resource");
}
}
@Configuration
@Configuration用于定义配置类,可替换xml配置文件,被注解的类内部包含有一个或多个被@Bean注解的方法,这些方法将会被AnnotationConfigApplicationContext或AnnotationConfigWebApplicationContext类进行扫描,并用于构建bean定义,初始化Spring容器。
简单来说,就是初始化bean所对应的对象,提供默认属性。
@Configuration
public class HumanConfig {
@Bean(name = "student",initMethod = "init")
public Human getStudent() {
Human student = new Human();
student.setName("Teacher");
return student;
}
@Bean(name = "teacher",destroyMethod = "destroy")
public Human getTeacher() {
Human teacher = new Human();
teacher.setName("Student");
return teacher;
}
}
@ConditionalOnWebApplication
只有当spring为web服务时,才使注解生效
@AutoConfigureAfter
在加载配置类之后再加载当前类
@ConditionalOnProperty
控制配置类是否生效
name
配置项的名字
havingValue
与配置的值对比
matchIfMissing
未配置属性时的匹配方式
@Bean
方法级别上的注解,产生一个被IOC容器所管理的bean。bean可以理解为一个豆子,一个对象。
创建一个类:
import lombok.Data;
@Data
public class Human implements SayInterface {
private String name;
@Override
public void say() {
System.out.println("Hello " + name);
}
public void init() {
System.out.println(name + " init");
}
public void destroy() {
System.out.println(name + " destroy");
}
}
创建一个配置类:
@Configuration
public class HumanConfig {
// 默认bean的名称和方法名相同
// 使用name定义bean的名称
// initMethod声明周期,创建后执行
@Bean(name = "student",initMethod = "init")
public Human getStudent() {
Human student = new Human();
student.setName("Teacher");
return student;
}