spring基本组件如上图:spring
最初使用xml配置文件,而后转向注解。数组
//配置类====配置文件 @Configuration public class MainConfig { //给容器中注册一个bean, 类型为返回值的类型, //注意以@Bean注册bean,Id默认为方法名,也可经过@Bean注解的值来修改 @Bean public Person person01(){ return new Person("username",20); } } public class MainTest2 { public static void main(String args[]){ //加载注解的配置文件 ApplicationContext app = new AnnotationConfigApplicationContext(MainConfig.class); //从容器中获取bean //Person person = (Person) app.getBean("person01"); //System.out.println(person); String[] namesForBean = app.getBeanNamesForType(Person.class); for(String name:namesForBean){ System.out.println(name); } } }
@Configuration @ComponentScan(value="com.enjoy.cap2", includeFilters={ @Filter(type=FilterType.ANNOTATION, classes={Controller.class}) }, useDefaultFilters=false) public class Cap2MainConfig { //给容器中注册一个bean, 类型为返回值的类型, @Bean public Person person01(){ return new Person("james",20); } }
@ComponentScan value:指定要扫描的包
excludeFilters = Filter[] 指定扫描的时候按照什么规则排除那些组件
includeFilters = Filter[] 指定扫描的时候只须要包含哪些组件
useDefaultFilters = false 默认是true,扫描全部组件,要改为false
----扫描规则以下
FilterType.ANNOTATION:按照注解
FilterType.ASSIGNABLE_TYPE:按照给定的类型;好比按BookService类型
FilterType.ASPECTJ:使用ASPECTJ表达式
FilterType.REGEX:使用正则指定
FilterType.CUSTOM:使用自定义规则,自已写类,实现TypeFilter接口session
//FilterType.CUSTOM的例子,经常使用
先新增自定义过滤规则类: TestTypeFilter
@ComponentScan(value="com.enjoy.cap2",includeFilters={app
@Filter(type=FilterType.CUSTOM,classes={TestTypeFilter.class})
},useDefaultFilters=false)ide
public class TestTypeFilter implements TypeFilter{ private ClassMetadata classMetadata; /* * MetadataReader:读取到当前正在扫描类的信息 * MetadataReaderFactory:能够获取到其余任何类信息 */ @Override public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException { //获取当前类注解的信息 AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata(); //获取当前正在扫描的类信息 classMetadata = metadataReader.getClassMetadata(); //获取当前类资源(类的路径) Resource resource = metadataReader.getResource(); String className = classMetadata.getClassName(); System.out.println("----->"+className); if(className.contains("er")){//当类包含er字符, 则匹配成功,返回true return true; } return false; } }
spring中bean默认是单例singleton,@Scope(“prototype”)为多实例。spa
//多实例 @Scope("prototype") @Bean public Person person(){ return new Person("username",20); }
@lazy当加入此注解时,则getBean调用的时候才会把实例加载到IOC容器。操作系统
public class WinCondition implements Condition{ /* *ConditionContext: 判断条件可使用的上下文(环境) *AnnotatedTypeMetadata: 注解的信息 * */ @Override public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { // TODO 是否为WINDOW系统 //能获取到IOC容器正在使用的beanFactory ConfigurableListableBeanFactory beanFactory = context.getBeanFactory(); //获取当前环境变量(包括咱们操做系统是WIN仍是LINUX??) Environment environment = context.getEnvironment(); String os_name = environment.getProperty("os.name"); if(os_name.contains("Windows")){ return true; } return false; } } //加入条件注解则会按自定义的逻辑注册,true时注册到容器 @Conditional(WinCondition.class) @Bean("lison") public Person lison(){ System.out.println("给容器中添加lison......."); return new Person("Lison",28); }
@Import(value = { Dog.class,Cat.class,JamesImportSelector.class,JamesImportBeanDefinitionRegistrar.class }) public class JamesImportSelector implements ImportSelector{ @Override public String[] selectImports(AnnotationMetadata importingClassMetadata){ //返回全类名的bean return new String[]{"com.enjoy.cap6.bean.Fish","com.enjoy.cap6.bean.Tiger"}; } } public class JamesImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar { /* *AnnotationMetadata:当前类的注解信息 *BeanDefinitionRegistry:BeanDefinition注册类 * 把全部须要添加到容器中的bean加入; * @Scope */ @Override public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { boolean bean1 = registry.containsBeanDefinition("com.enjoy.cap6.bean.Dog"); boolean bean2 = registry.containsBeanDefinition("com.enjoy.cap6.bean.Cat"); //若是Dog和Cat同时存在于咱们IOC容器中,那么建立Pig类, 加入到容器 //对于咱们要注册的bean, 给bean进行封装, if(bean1 && bean2){ RootBeanDefinition beanDefinition = new RootBeanDefinition(Pig.class); registry.registerBeanDefinition("pig", beanDefinition); } } }
给容器中注册组件的方式:prototype
1,@Bean: [导入第三方的类或包的组件],好比Person为第三方的类, 须要在咱们的IOC容器中使用code
2,包扫描+组件的标注注解(@ComponentScan: @Controller, @Service @Reponsitory @
Componet),通常是针对 咱们本身写的类,使用这个xml
3,@Import:[快速给容器导入一个组件] 注意:@Bean有点简单
a,@Import(要导入到容器中的组件):容器会自动注册这个组件,bean 的 id为全类名
b,ImportSelector:是一个接口,返回须要导入到容器的组件的全类名数组
c,ImportBeanDefinitionRegistrar:能够手动添加组件到IOC容器, 全部Bean的注册可使用BeanDifinitionRegistry,写JamesImportBeanDefinitionRegistrar实现ImportBeanDefinitionRegistrar接口便可