“这里是offer学院,帮你轻松拿offer”
嗨~大家好,我是学长!今天的你过得还好吗?
- 2022.11.30 -
本文章为【Spring】classpath扫描和组件管理相关知识,下边将对@Component 和及其派生出的其他注解,自动检测类和注册beanDifination,组件命名,为自动检测组件提供scope,使用过滤器自定义扫描,在组件中定义Bean元数据等进行详尽介绍~
本节我们可以通过【扫描类路径】隐式检测候选组件。 【候选组件】指的是通过扫描筛选并在容器中注册了相应beanDifination的类。这样就不需要使用XML来执行bean注册。 相反,你可以使用注解(例如,【@Component 】)。从Spring 3.0开始,Spring JavaConfig 项目提供的许多特性都是核心Spring框架的一部分。 这允许你使用Java而不是使用传统的XML文件来定义bean。
@Component 和及其派生出的其他注解:
自动检测类和注册beanDifination:
Spring可以自动检测类的信息,并将相应的【BeanDefinition】实例注册到【ApplicationContext】中。 例如,以下两个类适合这样的自动检测:
@Service
public class SimpleMovieLister {
private MovieFinder movieFinder;
public SimpleMovieLister(MovieFinder movieFinder) {
this.movieFinder = movieFinder;
}
}
@Repository
public class JpaMovieFinder implements MovieFinder {
// implementation elided for clarity
}
要自动检测这些类并注册相应的bean,你需要将【@ComponentScan】添加到你的【 @Configuration】类中,其中【basePackages】属性是这两个类的公共父包。说人话就是:指定一个包名,自动扫描会检测这个包及其子包下的所有类信息。
@Configuration
@ComponentScan(basePackages = "org.example")
public class AppConfig {
// ...
}
为简单起见,前面的示例可能使用了注解的value属性 (即@ComponentScan ("org.example"))。
当然我们可以使用以下XML代替,他们是等效的:
<?xml version="1.0" encoding="UTF-8"?>
注意:
组件命名:
当组件作为扫描过程的一部分被自动检测时,它的bean名是由该扫描器所知道的“BeanNameGenerator”策略生成的。
默认情况下,会使用【@Component】, 【@Repository】,【@Service】和【@Controller】注解的value值,因此将该名称会提供给相应的beanDefination。 如果你的注解不包含任何名称属性,会有默认bean名称生成器将返回【非首字母大写的非全限定类名】。
例如,如果检测到以下组件类,则名称为【myMovieLister】和【movieFinderImp】,这个和xml自动生成的标识符名称不同:
@Service("myMovieLister")
public class SimpleMovieLister {
// ...
}
@Repository
public class MovieFinderImpl implements MovieFinder {
// ...
}
为自动检测组件提供scope:
与spring管理的组件一样,自动检测组件的默认和最常见的作用域是“单例”。 然而,有时你需要一个不同的范围,可以由' @Scope '注解指定。 你可以在注解中提供作用域的名称,如下面的示例所示:
@Scope("prototype")
@Repository
public class MovieFinderImpl implements MovieFinder {
// ...
}
使用过滤器自定义扫描:
默认情况下,带有【@Component】、【@Repository】、【@Service】、【@Controller】、【@Configuration】注解的类是一定能被筛选器选中并进行注册的候选组件。 但是,你可以通过应用自定义过滤器来修改和扩展此行为,自由定制筛选哪些或不包含那些组件。 将它们作为@ComponentScan注解的includeFilters 或 excludeFilters 属性添加(或者作为XML配置中’
每个筛选器元素都需要’ type ‘和’ expression '属性。 下表描述了过滤选项:
下面的示例显示了忽略所有【@Repository】注解,而使用【stub】包下的类进行替换:
@Configuration
@ComponentScan(basePackages = "org.example",
includeFilters = @Filter(type = FilterType.REGEX, pattern = ".*Stub.*Repository"),
excludeFilters = @Filter(Repository.class))
public class AppConfig {
// ...
}
下面的例子显示了等效的XML:
【小知识】
你还可以通过在注解上设置useDefaultFilters=false 或通过提供use-default-filters="false" 作为
在组件中定义Bean元数据:
Spring组件还可以向容器提供beanDifination元数据。 可以使用 @Bean 注解来实现这一点。
@Component
public class FactoryMethodComponent {
@Bean
@Qualifier("public")
public TestBean publicInstance() {
return new TestBean("publicInstance");
}
public void doWork() {
// Component method implementation omitted
}
}
前面的类是一个Spring组件,它的【doWork()】方法中包含特定于应用程序的代码。 然而,它还提供了一个beanDifination,该beanDifination有一个引用方法【public Instance()】的工厂方法。 【@Bean注解】标识工厂方法,通过【@Qualifier】注解标识一个限定符值。 其他可以指定的方法级注解有【@Scope 】, 【@Lazy 】等。
下面的例子展示了如何做到这一点:
@Component
public class FactoryMethodComponent {
private static int i;
@Bean
@Qualifier("public")
public TestBean publicInstance() {
return new TestBean("publicInstance");
}
// use of a custom qualifier and autowiring of method parameters
@Bean
protected TestBean protectedInstance(
@Qualifier("public") TestBean spouse,
@Value("#{privateInstance.age}") String country) {
TestBean tb = new TestBean("protectedInstance", 1);
tb.setSpouse(spouse);
tb.setCountry(country);
return tb;
}
@Bean
private TestBean privateInstance() {
return new TestBean("privateInstance", i++);
}
}
✅Okey~ 今天的Spring教程内容就到这里!下期我们将继续讲解Spring的基于Java的容器配置,BeanFactory和FactoryBean,环境抽象,事件机制等进行详尽介绍~
我们下期再见!
END
文案编辑|offer学长
文案配图|offer学长
内容由:小新要变强(博主)分享
页面更新:2024-04-01
本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828
© CopyRight 2020-2024 All Rights Reserved. Powered By 71396.com 闽ICP备11008920号-4
闽公网安备35020302034903号