JDO java data object 99-03年
注解:
- 声明配置类 bean 早期从xml解析 配置类
- @configuration 相当于 配置文件
扫描的注解: @controller @Service @Respostry @Component
if(useDefaultFilters){
registerDefaultFilters();
}
this.includeFilters.add(new AnnotationTypeFilter(Componet.class))
以@Component--->
com.enjoy.cpa2
@Controller
@Component
@Service
IOC就是对我们Bean进行管理:bean 注册 实例化 管理
@Conditional条件注册bean
根据指定条件选择性地注册bean实例
1 package com.enjoy.cap5.config; 2 3 4 import com.enjoy.cap1.Person; 5 import org.springframework.context.annotation.Bean; 6 import org.springframework.context.annotation.Configuration; 7 8 9 @Configuration 10 public class Cap5MainConfig { 11 12 @Bean("person") // Bean的id 不设置id的时候,默认取的是方法名 13 public Person person(){ 14 System.out.println("给容器中添加person...."); 15 return new Person("person", 20); 16 } 17 18 @Bean("lison") 19 public Person lison(){ 20 System.out.println("给容器中添加lison...."); 21 return new Person("Lison", 20); 22 } 23 24 @Bean("james") // bean在容器中的ID为james,IOC容器MAP map.put("id", value); 25 public Person james(){ 26 System.out.println("给容器中添加james...."); 27 return new Person("james", 20); 28 } 29 30 // 创建的时候就会把bean map.put到容器当中 31 32 }
1 import com.enjoy.cap5.config.Cap5MainConfig; 2 import org.junit.Test; 3 import org.springframework.context.annotation.AnnotationConfigApplicationContext; 4 5 public class Cap5Test { 6 7 @Test 8 public void test01(){ 9 // 创建容器将bean加载进来 10 AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(Cap5MainConfig.class); 11 12 System.out.println("IOC容器创建完成........"); 13 14 } 15 }
需求:测试运行时候,如果操作系统是windows,就让Lison这个对象实例化到容器中,如果是LINUX,就是让james实例化到容器中。
实现条件
beanFactory
FactoryBean 和 BeanFactory 的区别:
- FactoryBean:可以把java实例bean通过FactoryBean注入到容器中
- BeanFactory:从容器中获取实例化后的bean
1 package com.enjoy.cap5.config; 2 3 4 import com.enjoy.cap1.Person; 5 import org.springframework.context.annotation.Bean; 6 import org.springframework.context.annotation.Conditional; 7 import org.springframework.context.annotation.Configuration; 8 9 10 @Configuration 11 public class Cap5MainConfig { 12 13 @Bean("person") // Bean的id 不设置id的时候,默认取的是方法名 14 public Person person(){ 15 System.out.println("给容器中添加person...."); 16 return new Person("person", 20); 17 } 18 19 @Conditional(WinCondition.class) 20 @Bean("lison") 21 public Person lison(){ 22 System.out.println("给容器中添加lison...."); 23 return new Person("Lison", 20); 24 } 25 26 @Conditional(LinCondition.class) 27 @Bean("james") // bean在容器中的ID为james,IOC容器MAP map.put("id", value); 28 public Person james(){ 29 System.out.println("给容器中添加james...."); 30 return new Person("james", 20); 31 } 32 33 // 创建的时候就会把bean map.put到容器当中 34 35 }
1 package com.enjoy.cap5.config; 2 3 import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; 4 import org.springframework.context.annotation.Condition; 5 import org.springframework.context.annotation.ConditionContext; 6 import org.springframework.core.env.Environment; 7 import org.springframework.core.type.AnnotatedTypeMetadata; 8 9 public class LinCondition implements Condition { 10 /** 11 * ConditionContext:判断条件可以使用的上下文(环境) 12 * AnnotatedTypeMetadata:注解的信息 13 * */ 14 public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) { 15 // TODO >> 是否为Windows 16 // 能够获取到IOC容器正在使用的beanFactory 17 ConfigurableListableBeanFactory beanFactory = conditionContext.getBeanFactory(); 18 // 获取当前环境变量(包括当前操作系统是win还是linux) 19 Environment environment = conditionContext.getEnvironment(); 20 String os_name = environment.getProperty("os.name"); 21 System.out.println(os_name); 22 23 if(os_name.contains("linux")){ 24 return true; 25 } 26 return false; // 返回false不起任何作用 27 } 28 }
1 package com.enjoy.cap5.config; 2 3 import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; 4 import org.springframework.context.annotation.Condition; 5 import org.springframework.context.annotation.ConditionContext; 6 import org.springframework.core.env.Environment; 7 import org.springframework.core.type.AnnotatedTypeMetadata; 8 9 public class WinCondition implements Condition { 10 /** 11 * ConditionContext:判断条件可以使用的上下文(环境) 12 * AnnotatedTypeMetadata:注解的信息 13 * */ 14 public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) { 15 // TODO >> 是否为Windows 16 // 能够获取到IOC容器正在使用的beanFactory 17 ConfigurableListableBeanFactory beanFactory = conditionContext.getBeanFactory(); 18 // 获取当前环境变量(包括当前操作系统是win还是linux) 19 Environment environment = conditionContext.getEnvironment(); 20 String os_name = environment.getProperty("os.name"); 21 System.out.println(os_name); 22 23 if(os_name.contains("Windows")){ 24 return true; 25 } 26 return false; // 返回false不起任何作用 27 } 28 }
Mac OS X
Mac OS X
给容器中添加person....
IOC容器创建完成........
@Import注册bean
1,手动添加组件到IOC容器;
2,使用ImportSelector自定义返回组件
3, 使用ImportBeanDefinitionRegistrar返回自定义组件
1 package com.enjoy.cap6.config; 2 3 4 import com.enjoy.cap1.Person; 5 import com.enjoy.cap6.bean.Cat; 6 import com.enjoy.cap6.bean.Dog; 7 import org.springframework.context.annotation.Bean; 8 import org.springframework.context.annotation.Configuration; 9 import org.springframework.context.annotation.Import; 10 11 12 @Configuration 13 @Import(value={Dog.class, Cat.class, JamesImportSelector.class}) // 相当与new一个对象放到容器中 14 15 public class Cap6MainConfig { 16 17 /** 18 * 给我们容器中注册组件: 19 * 1.@Bean:[导入第三方的类或包的组件],比如person为第三方的类,需要再IOC容器中使用 20 * 2.包扫描+组件的标注注解(@ComponentScan:@controller @Service @Component),一般是针对自己写的类。使用这个 21 * 3.@import:[快速给容器导入一个组件] 注意:@Bean有点简单 22 * a. @Import(要导入到容器中的组件):容器会自动注册这个组件,bean的id为全类名(路径+id) 23 * b. ImportSelector:是一个接口,返回需要导入到容器的组件的全类名数组 24 */ 25 // 容器启动时初始化person的bean实例 26 @Bean("person") 27 public Person person(){ 28 System.out.println("给容器中添加person...."); 29 return new Person("person", 20); 30 } 31 32 }
1 package com.enjoy.cap6.config; 2 3 import org.springframework.context.annotation.ImportSelector; 4 import org.springframework.core.type.AnnotationMetadata; 5 6 public class JamesImportSelector implements ImportSelector { 7 8 @Override 9 public String[] selectImports(AnnotationMetadata annotationMetadata) { 10 // 返回全类名的bean 11 return new String[]{"com.enjoy.cap6.bean.Fish", "com.enjoy.cap6.bean.Tiger"}; 12 } 13 }
1 import com.enjoy.cap6.config.Cap6MainConfig; 2 import org.junit.Test; 3 import org.springframework.context.annotation.AnnotationConfigApplicationContext; 4 5 public class Cap6Test { 6 7 @Test 8 public void test01(){ 9 // 创建容器将bean加载进来 10 AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(Cap6MainConfig.class); 11 12 System.out.println("IOC容器创建完成........"); 13 String[] beanDefinitionNames = app.getBeanDefinitionNames(); 14 15 for(String name: beanDefinitionNames){ 16 System.out.println(name); 17 } 18 19 } 20 }
给容器中添加person....
IOC容器创建完成........
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
cap6MainConfig
com.enjoy.cap6.bean.Dog
com.enjoy.cap6.bean.Cat
com.enjoy.cap6.bean.Fish
com.enjoy.cap6.bean.Tiger
person
/**
* 给我们容器中注册组件:
* 1.@Bean:[导入第三方的类或包的组件],比如person为第三方的类,需要再IOC容器中使用
* 2.包扫描+组件的标注注解(@ComponentScan:@controller @Service @Component),一般是针对自己写的类。使用这个
* 3.@import:[快速给容器导入一个组件] 注意:@Bean有点简单
* a. @Import(要导入到容器中的组件):容器会自动注册这个组件,bean的id为全类名(路径+id)
* b. ImportSelector:是一个接口,返回需要导入到容器的组件的全类名数组
* c. ImportBeanDefinitionRegistrar:可以手动天剑组件到IOC容器,所有Bean的注册可以使用BeanDefinitionRegistry
* 4.使用Spring提供的FactoryBean(工厂bean)进行注册:把bean注入到容器中
*/
1 package com.enjoy.cap6.config; 2 3 4 import com.enjoy.cap1.Person; 5 import com.enjoy.cap6.bean.Cat; 6 import com.enjoy.cap6.bean.Dog; 7 import org.springframework.context.annotation.Bean; 8 import org.springframework.context.annotation.Configuration; 9 import org.springframework.context.annotation.Import; 10 11 12 @Configuration 13 @Import(value={Dog.class, Cat.class, JamesImportSelector.class}) // 相当与new一个对象放到容器中 14 15 public class Cap6MainConfig { 16 17 /** 18 * 给我们容器中注册组件: 19 * 1.@Bean:[导入第三方的类或包的组件],比如person为第三方的类,需要再IOC容器中使用 20 * 2.包扫描+组件的标注注解(@ComponentScan:@controller @Service @Component),一般是针对自己写的类。使用这个 21 * 3.@import:[快速给容器导入一个组件] 注意:@Bean有点简单 22 * a. @Import(要导入到容器中的组件):容器会自动注册这个组件,bean的id为全类名(路径+id) 23 * b. ImportSelector:是一个接口,返回需要导入到容器的组件的全类名数组 24 * c. ImportBeanDefinitionRegistrar:可以手动天剑组件到IOC容器,所有Bean的注册可以使用BeanDefinitionRegistry 25 */ 26 // 容器启动时初始化person的bean实例 27 @Bean("person") 28 public Person person(){ 29 System.out.println("给容器中添加person...."); 30 return new Person("person", 20); 31 } 32 33 }
1 package com.enjoy.cap6.config; 2 3 import com.enjoy.cap6.bean.Pig; 4 import org.springframework.beans.factory.support.BeanDefinitionRegistry; 5 import org.springframework.beans.factory.support.RootBeanDefinition; 6 import org.springframework.context.annotation.ImportBeanDefinitionRegistrar; 7 import org.springframework.core.type.AnnotationMetadata; 8 9 public class JamesImportBeanfinitionRegistrar implements ImportBeanDefinitionRegistrar { 10 11 /** 12 * AnnotationMetadata:当前类的注解信息 13 * BeanDefinitionRegistry:BeanDefinition注册类 14 * 把所有需要添加到容器中的bean加入; 15 * 16 **/ 17 @Override 18 public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) { 19 20 // 面试官:当容器中存在cat dog 才往容器中添加pig 21 22 // 判断bean是否存在 23 boolean beanDog = beanDefinitionRegistry.containsBeanDefinition("com.enjoy.cap6.bean.Dog"); 24 boolean beanCat = beanDefinitionRegistry.containsBeanDefinition("com.enjoy.cap6.bean.Cat"); 25 26 //对于我们要注册的bean,给bean进行封装 RootBeanDefinition 27 28 // 如果dog和cat同时存在ioc容器中,那么创建pig类加入到容器当中。 29 if(beanCat && beanDog){ 30 RootBeanDefinition beanDefinition = new RootBeanDefinition(Pig.class); // 特有的容器封装 31 beanDefinitionRegistry.registerBeanDefinition("Pig", beanDefinition); 32 } 33 } 34 }
Error:(30, 49) java: 无法访问java.util.function.Supplier
找不到java.util.function.Supplier的类文件
java编译环境出错 打开File--->Projrct Struct 设置JDK版本解决
Factorybean接口实现
1,getObject()返回对象方法;
2,getObjectType返回对象类型
3, isSingleton()是否单例控制
1 package com.enjoy.cap6.config; 2 3 import com.enjoy.cap6.bean.Monkey; 4 import org.springframework.beans.factory.FactoryBean; 5 6 public class JamesFactoryBean implements FactoryBean<Monkey> { 7 @Override 8 public Monkey getObject() throws Exception { 9 return new Monkey(); 10 } 11 12 @Override 13 public Class<?> getObjectType() { 14 return Monkey.class; 15 } 16 17 // 是否单例模式 true 单实例 false 多实例 18 @Override 19 public boolean isSingleton() { 20 return false; 21 } 22 }
1 package com.enjoy.cap6.config; 2 3 import com.enjoy.cap1.Person; 4 import com.enjoy.cap6.bean.Cat; 5 import com.enjoy.cap6.bean.Dog; 6 import org.springframework.context.annotation.Bean; 7 import org.springframework.context.annotation.Configuration; 8 import org.springframework.context.annotation.Import; 9 10 @Configuration 11 @Import(value={Dog.class, Cat.class, JamesImportSelector.class, JamesImportBeanDefinitionRegistrar.class}) // 相当与new一个对象放到容器中 12 13 public class Cap6MainConfig { 14 15 /** 16 * 给我们容器中注册组件: 17 * 1.@Bean:[导入第三方的类或包的组件],比如person为第三方的类,需要再IOC容器中使用 18 * 2.包扫描+组件的标注注解(@ComponentScan:@controller @Service @Component),一般是针对自己写的类。使用这个 19 * 3.@import:[快速给容器导入一个组件] 注意:@Bean有点简单 20 * a. @Import(要导入到容器中的组件):容器会自动注册这个组件,bean的id为全类名(路径+id) 21 * b. ImportSelector:是一个接口,返回需要导入到容器的组件的全类名数组 22 * c. ImportBeanDefinitionRegistrar:可以手动天剑组件到IOC容器,所有Bean的注册可以使用BeanDefinitionRegistry 23 * 4.使用Spring提供的FactoryBean(工厂bean)进行注册:把bean注入到容器中 24 */ 25 // 容器启动时初始化person的bean实例 26 @Bean("person") 27 public Person person(){ 28 System.out.println("给容器中添加person...."); 29 return new Person("person", 20); 30 } 31 32 @Bean 33 public JamesFactoryBean jamesFactoryBean(){ 34 return new JamesFactoryBean(); 35 } 36 37 }
1 import com.enjoy.cap6.config.Cap6MainConfig; 2 import org.junit.Test; 3 import org.springframework.context.annotation.AnnotationConfigApplicationContext; 4 5 public class Cap6Test { 6 7 @Test 8 public void test01(){ 9 // 创建容器将bean加载进来 10 AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(Cap6MainConfig.class); 11 12 System.out.println("IOC容器创建完成........"); 13 String[] beanDefinitionNames = app.getBeanDefinitionNames(); 14 15 for(String name: beanDefinitionNames){ 16 System.out.println(name); 17 } 18 19 Object bean1 = app.getBean("jamesFactoryBean"); 20 System.out.println("bean的类型="+bean1.getClass()); 21 } 22 }
生命周期-初始化与销毁
如何定义和销毁3种方式;
- 1, 指定初始化和销毁方法
- 2,让Bean实现 InitializingBean(定义初始化逻辑)
- 3, 使用JSR250规则定义的两个注解来实现