在Spring Boot中,注册Bean主要有以下几种方式:
1. 使用@Component注解
在springboot创建类时添加@Component注解
点击查看代码
@Component
public class MyBean
{ ; // 类定义 }
2. 使用@Repository、@Service、@Controller注解
这些注解是@Component的特化,分别用于标记数据访问层(DAO层)、服务层和控制器层。使用这些注解可以让代码更加清晰,同时也便于Spring进行分层管理。
@Repository:用于标记数据访问层组件。@Service:用于标记服务层组件。@Controller:用于标记控制器层组件。
点击查看代码
``` @Service public class MyService { // 类定义 } ```3. 使用 @Bean 注解
如果你需要在配置类中显式地定义Bean,可以使用@Bean注解。这种方式通常用于那些需要通过方法创建的复杂Bean,或者当你想要在运行时动态创建Bean时。
点击查看代码
@Configuration
public class AppConfig {
@Bean
public MyBean myBean()
{ return new MyBean(); } }
4. 使用@Configuration和@Bean结合的方式创建配置类
这种方式结合了上面提到的使用@Configuration和@Bean的方法,适用于需要大量配置和复杂逻辑的情况。
点击查看代码
@Configuration
public class AppConfig
{ @Bean public MyService myService()
{ return new MyServiceImpl(); // 返回一个实现了MyService接口的类的实例 } }
5. 使用@Import注解导入其他配置类
如果你有多个配置类,可以使用@Import注解将它们导入到主配置类中。这样可以使配置更加模块化。
点击查看代码
@Configuration
@Import({AppConfig.class, AnotherConfig.class})
public class MainConfig { // 主配置类内容 }
关于扫描bean组件:
1. 使用@SpringBootApplication注解
当你使用@SpringBootApplication注解在你的主类上时,它内部已经包含了@ComponentScan,并且默认会扫描当前类所在的包及其子包
点击查看代码
@SpringBootApplication//MyApplication及其所在包和子包中组件都会被扫描
public class MyApplication {public static void main(String[] args) {SpringApplication.run(MyApplication.class, args);}
}
2.自定义包扫描
2.1 在@SpringBootApplication注解中指定scanBasePackages属性
点击查看代码
@SpringBootApplication(scanBasePackages = "com.example.myapp")//指定扫描的组件名
public class MyApplication {public static void main(String[] args) {SpringApplication.run(MyApplication.class, args);}
}
2.2.(通过@ComponentScan)自动扫描包中的组件:
Spring Boot默认会扫描启动类所在的包及其子包下的所有带有@Component、@Service、@Repository、@Controller等注解的类,并将它们注册为Spring容器中的Bean。
你可以通过在主应用类或者配置类上使用@ComponentScan注解来指定Spring Boot自动扫描的包路径,从而自动注册这些包下的所有Bean。(注意扫描路径外的组件不会扫描)
点击查看代码
@SpringBootApplication
@ComponentScan(basePackages = "com.example.myapp") // 指定扫描的组件名
public class MyApplication
{
public static void main(String[] args)
{ SpringApplication.run(MyApplication.class, args); }
}
也可以在特定的配置类上使用@ComponentScan来指定扫描的包:也可以在特定的配置类上使用@ComponentScan来指定扫描的包:
点击查看代码
@Configuration
@ComponentScan(basePackages = "com.example.myapp")
public class AppConfig {
}@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class}) // 示例,排除自动配置类
public class MyApplication {public static void main(String[] args) {SpringApplication app = new SpringApplication(MyApplication.class);app.setRegisterShutdownHook(true); // 确保应用正确关闭app.run(args);}
}
使用排除模式(Exclude Filters)
如果你只想包含或排除特定的组件,你可以使用includeFilters或excludeFilters属性
点击查看代码
@ComponentScan(basePackages = "com.example.myapp", excludeFilters = {@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = SpecificComponent.class)
})
public class AppConfig {
}
在application.properties或application.yml中设置扫描路径
properties
spring.main.scan-package=com.example.myapp
yaml
spring: main: scan-package: com.example.myapp
bean注入:
1. 使用@Autowired注解
@Autowired注解可以自动装配Spring容器中的Bean。你可以在构造器、字段或方法上使用它。
点击查看代码
@Component
public class MyService {// 通过字段注入@Autowiredprivate MyDependency myDependency;// 通过构造器注入private final MyDependency myDependency;@Autowiredpublic MyService(MyDependency myDependency) {this.myDependency = myDependency;}// 通过Setter方法注入@Autowiredpublic void setMyDependency(MyDependency myDependency) {this.myDependency = myDependency;}
}
2. 使用@Resource注解
@Resource注解是Java标准,用于依赖注入。它可以通过名称或类型来装配Bean
@Resource
@Component
public class MyService {// 通过类型注入@Resourceprivate MyDependency myDependency;
}
3. 使用@Inject注解(JSR-330标准)
@Inject注解是JSR-330(Java依赖注入)标准的一部分,用于依赖注入。它比@Autowired更简洁,但在Spring中通常不常用,因为@Autowired提供了更多的灵活性
@Inject
@Component
public class MyService {@Injectprivate MyDependency myDependency;
}
4. 使用构造函数注入(推荐方式)
构造函数注入确保了依赖项在对象创建时就已经被注入,从而使得对象的状态在创建时就被确定,这是一种更清晰和更安全的依赖注入方式
点击查看代码
@Component
public class MyService {private final MyDependency myDependency;@Autowired // 或使用 @Inject,两者效果相同但 @Autowired 是 Spring 特有的,更常用。public MyService(MyDependency myDependency) {this.myDependency = myDependency;}
}
5. 使用@Qualifier注解解决歧义
当有多个相同类型的Bean候选时,你可以使用@Qualifier注解来指定具体的Bean。
点击查看代码
@Component
public class MyService {@Autowired@Qualifier("specificBean") // 指定具体的Bean名称或变量名private MyDependency myDependency;
}
或者使用@Primary注解标注首选的Bean:
点击查看代码
@Component
@Primary // 标记首选的Bean,当存在多个相同类型的Bean时,Spring将自动选择这个Bean进行注入。
public class PrimaryMyDependency implements MyDependency { }
6. 使用@Lazy注解实现懒加载(Lazy Loading)
点击查看代码
@Component
public class MyService {@Autowired // 或者 @Inject 和 @Resource 都支持 @Lazy 注解。 例如: @Autowired(required = false) @Lazy 也可以用在字段或方法上。 默认情况下,如果找不到Bean会抛出异常,设置 required = false 可以避免这种情况。 例如: @Autowired(required = false) @Lazy private MyDependency myDependency; 这样即使没有找到对应的Bean也不会抛出异常。 而是将myDependency设置为null。 但通常不推荐这种方式,因为它可能导致NullPointerException。 更合适的做法是使用 Optional<MyDependency> 来避免NullPointerException。 例如: @Autowired(required = false) private Optional<MyDependency> myDependency; 这样即使没有找到对应的Bean,myDependency也不会是null,而是Optional.empty()。 这样在使用时就需要判断是否存在值了。