一、Spring 组件注解
1. @CompentScan 包扫描
@Configuration
@ComponentScan(basePackages = {"com.qs.springannotation.component_scan"},
excludeFilters = {
@ComponentScan.Filter(type = FilterType.ANNOTATION, value = {Controller.class}),
@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = {UserService.class}),
@ComponentScan.Filter(type = FilterType.CUSTOM, value = CustomTypeFilter.class),
},
useDefaultFilters = false,
includeFilters = {
@ComponentScan.Filter(type = FilterType.ANNOTATION, value = Repository.class)
})
public class ComponentScanConfig {
public ComponentScanConfig() {
System.out.printf("`%s`无参构造", this.getClass().getName()).println();
}
}
public class CustomTypeFilter implements TypeFilter {
@Override
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
Resource resource = metadataReader.getResource();
ClassMetadata classMetadata = metadataReader.getClassMetadata();
AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
String className = classMetadata.getClassName();
System.out.printf("类的路径:%s", className).println();
return className.contains("dao");
}
}
public enum FilterType {
ANNOTATION,
ASSIGNABLE_TYPE,
ASPECTJ,
REGEX,
CUSTOM
}
2. @Scope 范围
@Scope(scopeName = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
@Bean("personPrototype")
public Person personPrototype() {
return new Person("personPrototype");
}
@Test
public void testScope() {
System.out.println("------------------------------");
AnnotationConfigApplicationContext applicationContext =
new AnnotationConfigApplicationContext(BeanConfig.class);
System.out.println("------------------------------");
Object bean = applicationContext.getBean("personPrototype");
System.out.println(bean);
Object bean2 = applicationContext.getBean("personPrototype");
System.out.println(bean2);
applicationContext.close();
}
3. @Lazy 懒加载
@Lazy
@Bean(name = "personLazy")
public Person personLazy() {
return new Person("personLazy");
}
@Test
public void testLazy() {
System.out.println("------------------------------");
AnnotationConfigApplicationContext applicationContext =
new AnnotationConfigApplicationContext(BeanConfig.class);
System.out.println("------------------------------");
Object bean = applicationContext.getBean("personLazy");
System.out.println(bean);
}
4. @Conditional 指定依赖的条件
public class ConditionalConfig {
@Bean
public Qs qs() {
return new Qs(1);
}
@Conditional(QsCondition.class)
@Bean
public QsHome qsHome(Qs qs) {
return new QsHome(qs);
}
}
public class QsCondition implements Condition {
@Override
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
return conditionContext.getBeanFactory().containsBean("qs");
}
}
@Test
public void testConditional() {
System.out.println("------------------------------");
AnnotationConfigApplicationContext applicationContext =
new AnnotationConfigApplicationContext(ConditionalConfig.class);
System.out.println("------------------------------");
Qs qs = applicationContext.getBean(Qs.class);
System.out.println(qs);
QsHome qsHome = applicationContext.getBean(QsHome.class);
System.out.println(qsHome);
}
5. @Import 导入组件
@Configuration
@Import({QsHome.class, MyImportSelector.class, MyImportBeanDefinitionRegistrar.class})
public class ImportConfig {
}
public class MyImportSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
return new String[]{"com.qs.springannotation.import_bean.Qs"};
}
}
- ImportBeanDefinitionRegistrar 注册 Bean 定义。
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) {
RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(QsHome.class);
beanDefinitionRegistry.registerBeanDefinition("qsHome2", rootBeanDefinition);
}
}
6. @AutoWired 自动装配
@Data
@Service
public class AutowiredService {
private int flag = 0;
* 比如:容器中有二个`AutowiredDao`类型的组件,`autowiredDao`和`autowiredDao1`。
* 1. 通过`@AutoWired`来修饰的`autowiredDao`属性名称时,那么就加载容器的`autowiredDao`组件。
* 2. 若属性名称为`autowiredDao1`时,那么就加载`autowiredDao1`组件。
*/
@Autowired
private AutowiredDao autowiredDao;
@Autowired
private AutowiredDao autowiredDao1;
@Autowired(required = false)
@Qualifier(value = "autowiredDao9")
private AutowiredDao autowiredDao9;
}
6.1 @Autowired 方法注入
@Bean
public AutowiredMethodService autowiredMethodService2(@Autowired AutowiredDao autowiredDao) {
AutowiredMethodService service = new AutowiredMethodService();
service.setAutowiredDao(autowiredDao);
return service;
}
@Data
@Primary
@Service
public class AutowiredMethodService {
@Autowired
private AutowiredDao autowiredDao;
public AutowiredMethodService() {
System.out.printf("`%s`无参构造", this.getClass().getName()).println();
}
@Autowired
public AutowiredMethodService(AutowiredDao autowiredDao1) {
System.out.printf("`%s`有参构造,`autowiredDao = %s`", this.getClass().getName(), autowiredDao).println();
this.autowiredDao = autowiredDao1;
}
public AutowiredDao getAutowiredDao() {
return autowiredDao;
}
@Autowired
public void setAutowiredDao(AutowiredDao autowiredDao2) {
System.out.printf("`%s`.setAutowiredDao,`autowiredDao = %s`", this.getClass().getName(), autowiredDao).println();
this.autowiredDao = autowiredDao2;
}
}
7. @Qualifier 指定名称装配
@Data
@Service
public class QualifierService {
private int flag = 1;
* `@AutoWired`默认使用`BY_NAME`。
* 当发现多个`同类型的Bean`,就通过`BY_NAME`。
* 需要通过名称装配,使用`@Qualifier`指定名称装配。
*/
@Qualifier(value = "autowiredDao1")
@Autowired
private AutowiredDao autowiredDao;
@Qualifier(value = "autowiredDao")
@Autowired
private AutowiredDao autowiredDao1;
}
8. @Primary 存在多个按类型装配时标记默认的
@Primary
@Bean
public AutowiredDao autowiredDao2() {
AutowiredDao dao = new AutowiredDao();
dao.setFlag(2);
return dao;
}
@Primary
@Bean(autowire = Autowire.BY_TYPE)
public AutowiredService autowiredService3() {
AutowiredService service = new AutowiredService();
service.setFlag(3);
return service;
}
@Data
@Service
public class PrimaryService {
private int flag = 2;
@Autowired
private AutowiredDao autowiredDao;
@Qualifier(value = "autowiredDao1")
@Autowired
private AutowiredDao autowiredDao1;
@Autowired
private AutowiredDao autowiredDao2;
}
10. @Resource JSR250 规范
@Data
@Service
public class ResourceService {
@Resource
private AutowiredDao resourceDao;
}
11. @InJect JSR330 规范
@Service
@Data
public class InjectService {
@Inject
private AutowiredDao injectDao;
}
二、Spring 配置注解
1. @Profile 环境注入
* `EmbeddedValueResolverAware`接口,内嵌式值解析器。
*/
@Configuration
@PropertySource(value = {"classpath:ds.properties"})
public class ProfileConfig implements EmbeddedValueResolverAware {
private String classDriver;
private String jdbcUrl;
@Value("${ds.username}")
private String userName;
@Value("${ds.password}")
private String password;
@Override
public void setEmbeddedValueResolver(StringValueResolver stringValueResolver) {
this.jdbcUrl = stringValueResolver.resolveStringValue("${ds.jdbcUrl}");
this.classDriver = stringValueResolver.resolveStringValue("${ds.classDriver}");
}
@Bean
@Profile(value = "test")
public DataSource testDS() {
return buildDataSource(new DruidDataSource());
}
@Bean
@Profile(value = "dev")
public DataSource devDS() {
return buildDataSource(new DruidDataSource());
}
@Bean
@Profile(value = "prod")
public DataSource prodDS() {
return buildDataSource(new DruidDataSource());
}
private DataSource buildDataSource(DruidDataSource dataSource) {
dataSource.setDriverClassName(classDriver);
dataSource.setUrl(jdbcUrl);
dataSource.setUsername(userName);
dataSource.setPassword(password);
return dataSource;
}
}
AnnotationConfigApplicationContext applicationContext =
new AnnotationConfigApplicationContext();
applicationContext
.getEnvironment()
.setActiveProfiles("test", "dev");
2. @PropertySource + @Value 组件赋值
@Configuration
@PropertySource(value = {"classpath:person.properties"})
public class ValueConfig {
@Bean
public Person person() {
return new Person();
}
}
@Data
public class Person {
@Value("骑士")
private String firstName;
@Value("#{28-8}")
private Integer age;
@Value("${person.lastName}")
private String lastName;
}