- spring:4.3.18.RELEASE
- ide:IntelliJ IDEA 2018.1.7
- jdk:jdk1.8.0_201
1.配置类代替xml文件,@Bean注解代替bean标签
/** * BeanConfig.java * 配置类代替xml文件 */ @Configuration public class BeanConfig { /** * @Bean注解代替xml中bean标签 */ @Bean public Person person() { return new Person(1, "y"); } } /** * BeanConfigTest.java */ public class BeanConfigTest { static AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(BeanConfig.class); public static void main(String[] args) { printBeanDefinitionNames(); } private static void printBeanDefinitionNames() { String[] beanDefinitionNames = context.getBeanDefinitionNames(); for (String name : beanDefinitionNames) { System.out.println(name); } } } console: org.springframework.context.annotation.internalConfigurationAnnotationProcessor org.springframework.context.annotation.internalAutowiredAnnotationProcessor org.springframework.context.annotation.internalRequiredAnnotationProcessor org.springframework.context.annotation.internalCommonAnnotationProcessor org.springframework.context.event.internalEventListenerProcessor org.springframework.context.event.internalEventListenerFactory beanConfig person
ps:这样会以方法名作为bean的名称,可以在@Bean中覆盖掉它
2.注解形式包扫描进行组件注册
/** * ComponentScanConfig.java * 包扫描注解@ComponentScan */ @Configuration @ComponentScan("cn.yyyyy.controller") // @ComponentScan(value = "cn.yyyyy", excludeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {Controller.class})}) // @ComponentScan(value = "cn.yyyyy", excludeFilters = {@ComponentScan.Filter(type = FilterType.CUSTOM, classes = {MyScanFilter.class})}) public class ComponentScanConfig { } /** * ComponentScanConfigTest.class */ public class ComponentScanConfigTest { static AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ComponentScanConfig.class); public static void main(String[] args) { printBeanDefinitionNames(); } private static void printBeanDefinitionNames() { String[] beanDefinitionNames = context.getBeanDefinitionNames(); for (String name : beanDefinitionNames) { System.out.println(name); } } } console: org.springframework.context.annotation.internalConfigurationAnnotationProcessor org.springframework.context.annotation.internalAutowiredAnnotationProcessor org.springframework.context.annotation.internalRequiredAnnotationProcessor org.springframework.context.annotation.internalCommonAnnotationProcessor org.springframework.context.event.internalEventListenerProcessor org.springframework.context.event.internalEventListenerFactory componentScanConfig personController
ps:包扫描形式需要被扫描的类上面有@Component注解才会被注册,另外可以定义过滤规则(排除或包括),贴一下MyScanFilter.java代码
/** * MyScanFilter.java */ public class MyScanFilter implements TypeFilter { @Override public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException { ClassMetadata classMetadata = metadataReader.getClassMetadata(); System.out.println("---> " + classMetadata.getClassName()); return true; } }
3.懒加载
/** * LazyConfig.java * 根据console的先后顺序判断出只有获取bean的时候才会创建实例 */ @Configuration public class LazyConfig { @Lazy @Bean("lazyPerson") public Person person() { System.out.println("---> Person loaded"); return new Person(3, "y"); } } /** * LazyConfigTest.java */ public class LazyConfigTest { static AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(LazyConfig.class); public static void main(String[] args) { printBeanDefinitionNames(); printLine(); printBeans(); } private static void printBeanDefinitionNames() { String[] beanDefinitionNames = context.getBeanDefinitionNames(); for (String name : beanDefinitionNames) { System.out.println(name); } } private static void printBeans() { Map<String, Person> beans = context.getBeansOfType(Person.class); System.out.println(beans); } private static void printLine() { System.out.println("---------------------------------"); } } console:(省略了一些spring组件) lazyConfig lazyPerson --------------------------------- ---> Person loaded {lazyPerson=Person{id=3, name='y'}}
4.条件注册@Conditional
/** * ConditionalConfig.java * 根据是否符合条件注册,自定义的条件需要实现Condition接口,参见@Conditional */ @Configuration public class ConditionalConfig { @Bean("ConditionalPerson") @Conditional({PersonConditional.class}) public Person person() { return new Person(1, "conditional man"); } } public class ConditionalConfigTest { static AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ConditionalConfig.class); public static void main(String[] args) { printBeanDefinitionNames(); } private static void printBeanDefinitionNames() { String[] beanDefinitionNames = context.getBeanDefinitionNames(); for (String name : beanDefinitionNames) { System.out.println(name); } } } console: PersonConditional matches() execute return false org.springframework.context.annotation.internalConfigurationAnnotationProcessor org.springframework.context.annotation.internalAutowiredAnnotationProcessor org.springframework.context.annotation.internalRequiredAnnotationProcessor org.springframework.context.annotation.internalCommonAnnotationProcessor org.springframework.context.event.internalEventListenerProcessor org.springframework.context.event.internalEventListenerFactory conditionalConfig
5.作用域注解@Scope
/** * ScopeConfig.java * 作用域设置(默认单例) * 如果设置为prototype 那么容器启动不会创建该实例,但是每次获取会创建新的实例 */ @Configuration public class ScopeConfig { @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) @Bean("ScopePerson") public Person person() { System.out.println("ScopePerson created"); return new Person(2, "y"); } } public class ScopeConfigTest { static AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ScopeConfig.class); public static void main(String[] args) { printBeanDefinitionNames(); printLine(); System.out.println(samePerson()); } private static void printBeanDefinitionNames() { String[] beanDefinitionNames = context.getBeanDefinitionNames(); for (String name : beanDefinitionNames) { System.out.println(name); } } private static void printLine() { System.out.println("---------------------------------"); } private static boolean samePerson() { Person person1 = context.getBean(Person.class); Person person2 = context.getBean(Person.class); return person1 == person2; } } console:(省略一些spring组件) scopeConfig ScopePerson --------------------------------- ScopePerson created ScopePerson created false
6.直接注册一个类@Import
/** * ImportConfig.java * @Import和@Bean都适用于将第三方组件注册到容器,如果简单注册@Import比较简便 * @ComponentScan模式适用于自己开发的组件(带注解) */ @Configuration @Import({Red.class}) public class ImportConfig { } public class ImportConfigTest { static AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ImportConfig.class); public static void main(String[] args) { printBeanDefinitionNames(); } private static void printBeanDefinitionNames() { String[] beanDefinitionNames = context.getBeanDefinitionNames(); for (String name : beanDefinitionNames) { System.out.println(name); } } } console:(省略一些spring的组件) importConfig cn.yyyyy.bean.Red
7.自定义选择器注册
/** * ImportSelectorConfig.java * 还可以自定义选择器(MyImportSelector),需要实现ImportSelector接口 */ @Configuration @Import(MyImportSelector.class) public class ImportSelectorConfig { } public class MyImportSelector implements ImportSelector { @Override public String[] selectImports(AnnotationMetadata importingClassMetadata) { // return new String[0]; return new String[]{"cn.yyyyy.bean.Red"}; } } public class ImportSelectorConfigTest { static AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ImportSelectorConfig.class); public static void main(String[] args) { printBeanDefinitionNames(); } private static void printBeanDefinitionNames() { String[] beanDefinitionNames = context.getBeanDefinitionNames(); for (String name : beanDefinitionNames) { System.out.println(name); } } } console:(省略一些spring组件) MyImportSelector selectImports execute importSelectorConfig cn.yyyyy.bean.Red