Spring注解
AnnotationConfigApplicationContext
组件添加
@Configuration+@Bean
XML文件方式
Person
1. public class Person { 2. 3. private String name; 4. 5. private Integer age; 6. 7. private String nickName; 8. 9. public String getNickName() { 10. return nickName; 11. } 12. public void setNickName(String nickName) { 13. this.nickName = nickName; 14. } 15. public String getName() { 16. return name; 17. } 18. public void setName(String name) { 19. this.name = name; 20. } 21. public Integer getAge() { 22. return age; 23. } 24. public void setAge(Integer age) { 25. this.age = age; 26. } 27. 28. public Person(String name, Integer age) { 29. super(); 30. this.name = name; 31. this.age = age; 32. } 33. public Person() { 34. super(); 35. // TODO Auto-generated constructor stub 36. } 37. @Override 38. public String toString() { 39. return "Person [name=" + name + ", age=" + age + ", nickName=" + nickName + "]"; 40. } 41. } 42. beans.xml-配置文件 43. <?xml version="1.0" encoding="UTF-8"?> 44. <beans xmlns="http://www.springframework.org/schema/beans" 45. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 46. xmlns:context="http://www.springframework.org/schema/context" 47. xmlns:aop="http://www.springframework.org/schema/aop" 48. xmlns:tx="http://www.springframework.org/schema/tx" 49. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 50. http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd 51. http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd 52. http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd"> 53. 54. <context:component-scan base-package="com.atguigu" use-default-filters="false"></context:component-scan> 55. <bean id="person" class="com.atguigu.bean.Person"> 56. <property name="age" value="18"></property> 57. <property name="name" value="zhangsan"></property> 58. </bean> 59. </beans> 60. MainTest 61. public class MainTest { 62. 63. @SuppressWarnings("resource") 64. public static void main(String[] args) { 65. ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml"); 66. Person bean = (Person) applicationContext.getBean("person"); 67. System.out.println(bean); 68. } 69. }
输出
Person [name=zhangsan, age=18, nickName=null]
注解方式
1. //配置类==配置文件 2. @Configuration //告诉Spring这是一个配置类 3. public class MainConfig { 4. 5. //给容器中注册一个Bean;类型为返回值的类型,id默认是用方法名作为id(就是bean的名字),在这里就是person01 6. @Bean 7. public Person person01(){ 8. return new Person("lisi", 20); 9. } 10. 11. } 12. 或者以下面的这种方式 13. 14. //配置类==配置文件 15. @Configuration //告诉Spring这是一个配置类 16. public class MainConfig { 17. 18. //这里bean的name就是person 19. @Bean("person") 20. public Person person01(){ 21. return new Person("lisi", 20); 22. } 23. 24. } 25. @ComponentScans 26. //配置类==配置文件 27. @Configuration //告诉Spring这是一个配置类 28. 29. @ComponentScans( 30. value = { 31. @ComponentScan(value="com.atguigu",includeFilters = { 32. /* @Filter(type=FilterType.ANNOTATION,classes={Controller.class}), 33. @Filter(type=FilterType.ASSIGNABLE_TYPE,classes={BookService.class}),*/ 34. @Filter(type=FilterType.CUSTOM,classes={MyTypeFilter.class}) 35. },useDefaultFilters = false) 36. } 37. ) 38. //@ComponentScan value:指定要扫描的包 39. //excludeFilters = Filter[] :指定扫描的时候按照什么规则排除那些组件 40. //includeFilters = Filter[] :指定扫描的时候只需要包含哪些组件 41. //FilterType.ANNOTATION:按照注解 42. //FilterType.ASSIGNABLE_TYPE:按照给定的类型; 43. //FilterType.ASPECTJ:使用ASPECTJ表达式 44. //FilterType.REGEX:使用正则指定 45. //FilterType.CUSTOM:使用自定义规则 46. public class MainConfig { 47. 48. //给容器中注册一个Bean;类型为返回值的类型,id默认是用方法名作为id 49. @Bean("person") 50. public Person person01(){ 51. return new Person("lisi", 20); 52. } 53. 54. }
自定义TypeFilter指定包扫描规则
1. public class MyTypeFilter implements TypeFilter { 2. 3. /** 4. * metadataReader:读取到的当前正在扫描的类的信息 5. * metadataReaderFactory:可以获取到其他任何类信息的 6. */ 7. @Override 8. public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) 9. throws IOException { 10. // TODO Auto-generated method stub 11. //获取当前类注解的信息 12. AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata(); 13. //获取当前正在扫描的类的类信息 14. ClassMetadata classMetadata = metadataReader.getClassMetadata(); 15. //获取当前类资源(类的路径) 16. Resource resource = metadataReader.getResource(); 17. 18. String className = classMetadata.getClassName(); 19. System.out.println("--->"+className); 20. if(className.contains("er")){ 21. return true; 22. } 23. return false; 24. } 25. 26. } 27. @Scope 28. @Configuration 29. public class MainConfig2 { 30. 31. /** 32. * @see ConfigurableBeanFactory#SCOPE_PROTOTYPE 任何环境都可以使用 33. * @see ConfigurableBeanFactory#SCOPE_SINGLETON 任何环境都可以使用 34. * @see org.springframework.web.context.WebApplicationContext#SCOPE_REQUEST request 只能在web容器里用 35. * @see org.springframework.web.context.WebApplicationContext#SCOPE_SESSION sesssion 只能在web容器里用 36. * 37. * @Scope:调整作用域 38. * prototype:多实例的:ioc容器启动并不会去调用方法创建对象放在容器中。 39. * 每次获取的时候才会调用方法创建对象; 40. * singleton:单实例的(默认值):ioc容器启动会调用方法创建对象放到ioc容器中。 41. * 以后每次获取就是直接从容器(map.get())中拿, 42. * request:同一次请求创建一个实例 43. * session:同一个session创建一个实例 44. * 45. * 默认是单实例的 46. * 47. */ 48. @Scope("prototype") 49. @Lazy 50. @Bean("person") 51. public Person person(){ 52. System.out.println("给容器中添加Person...."); 53. return new Person("张三", 25); 54. } 55. 56. } 57. @Lazy 58. @Configuration 59. public class MainConfig2 { 60. 61. /** 62. * 63. * 懒加载: 64. * 单实例bean:默认在容器启动的时候创建对象; 65. * 懒加载:容器启动不创建对象。第一次使用(获取)Bean创建对象,并初始化; 66. * 67. */ 68. @Lazy 69. @Bean("person") 70. public Person person(){ 71. System.out.println("给容器中添加Person...."); 72. return new Person("张三", 25); 73. }
@Conditional
MainConfig2
1. //类中组件统一设置。满足当前条件,这个类中配置的所有bean注册才能生效; 2. @Conditional({WindowsCondition.class}) 3. @Configuration 4. public class MainConfig2 { 5. 6. 7. /** 8. * @Conditional({Condition}) : 按照一定的条件进行判断,满足条件给容器中注册bean 9. * 10. * 如果系统是windows,给容器中注册("bill") 11. * 如果是linux系统,给容器中注册("linus") 12. */ 13. 14. @Bean("bill") 15. public Person person01(){ 16. return new Person("Bill Gates",62); 17. } 18. 19. @Conditional(LinuxCondition.class) 20. @Bean("linus") 21. public Person person02(){ 22. return new Person("linus", 48); 23. } 24. }
LinuxCondition
1. //判断是否linux系统 2. public class LinuxCondition implements Condition { 3. 4. /** 5. * ConditionContext:判断条件能使用的上下文(环境) 6. * AnnotatedTypeMetadata:注释信息 7. */ 8. @Override 9. public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { 10. // TODO是否linux系统 11. //1、能获取到ioc使用的beanfactory 12. ConfigurableListableBeanFactory beanFactory = context.getBeanFactory(); 13. //2、获取类加载器 14. ClassLoader classLoader = context.getClassLoader(); 15. //3、获取当前环境信息 16. Environment environment = context.getEnvironment(); 17. //4、获取到bean定义的注册类 18. BeanDefinitionRegistry registry = context.getRegistry(); 19. 20. String property = environment.getProperty("os.name"); 21. 22. //可以判断容器中的bean注册情况,也可以给容器中注册bean 23. boolean definition = registry.containsBeanDefinition("person"); 24. if(property.contains("linux")){ 25. return true; 26. } 27. 28. return false; 29. }
WindowsCondition
1. //判断是否windows系统 2. public class WindowsCondition implements Condition { 3. 4. @Override 5. public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { 6. Environment environment = context.getEnvironment(); 7. String property = environment.getProperty("os.name"); 8. if(property.contains("Windows")){ 9. return true; 10. } 11. return false; 12. } 13. 14. }
@Import
MainConfig2
1. @Configuration 2. @Import({Color.class,Red.class,MyImportSelector.class,MyImportBeanDefinitionRegistrar.class}) 3. //@Import导入组件,id默认是组件的全类名 4. public class MainConfig2 { 5. 6. /** 7. * 给容器中注册组件; 8. * 1)、包扫描+组件标注注解(@Controller/@Service/@Repository/@Component)[只能注册自己写的类] 9. * 2)、@Bean[导入的第三方包里面的组件] 10. * 3)、@Import[快速给容器中导入一个组件] 11. * 1)、@Import(要导入到容器中的组件);容器中就会自动注册这个组件,id默认是全类名 12. * 2)、ImportSelector:返回需要导入的组件的全类名数组; 13. * 3)、ImportBeanDefinitionRegistrar:手动注册bean到容器中 14. */ 15. @Bean 16. public ColorFactoryBean colorFactoryBean(){ 17. return new ColorFactoryBean(); 18. } 19. }
MyImportSelector
1. //自定义逻辑返回需要导入的组件 2. public class MyImportSelector implements ImportSelector { 3. 4. //返回值,就是到导入到容器中的组件全类名 5. //AnnotationMetadata:@Import引入MyImportSelector的类的所有注解信息 6. @Override 7. public String[] selectImports(AnnotationMetadata importingClassMetadata) { 8. //importingClassMetadata.get 9. //方法不要返回null值,不然会报错 10. return new String[]{"com.atguigu.bean.Blue","com.atguigu.bean.Yellow"}; 11. } 12. 13. }
MyImportBeanDefinitionRegistrar
1. public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar { 2. 3. /** 4. * AnnotationMetadata:当前类的注解信息 5. * BeanDefinitionRegistry:BeanDefinition注册类; 6. * 把所有需要添加到容器中的bean;调用 7. * BeanDefinitionRegistry.registerBeanDefinition手工注册进来 8. */ 9. @Override 10. public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { 11. 12. boolean definition = registry.containsBeanDefinition("com.atguigu.bean.Red"); 13. boolean definition2 = registry.containsBeanDefinition("com.atguigu.bean.Blue"); 14. if(definition && definition2){ 15. //指定Bean定义信息;(Bean的类型,Bean。。。) 16. RootBeanDefinition beanDefinition = new RootBeanDefinition(RainBow.class); 17. //注册一个Bean,指定bean名 18. registry.registerBeanDefinition("rainBow", beanDefinition); 19. } 20. } 21. 22. } 23. public class Color { 24. 25. private Car car; 26. 27. public Car getCar() { 28. return car; 29. } 30. 31. public void setCar(Car car) { 32. this.car = car; 33. } 34. 35. @Override 36. public String toString() { 37. return "Color [car=" + car + "]"; 38. } 39. 40. } 41. public class Blue { 42. 43. public Blue(){ 44. System.out.println("blue...constructor"); 45. } 46. 47. public void init(){ 48. System.out.println("blue...init..."); 49. } 50. 51. public void detory(){ 52. System.out.println("blue...detory..."); 53. } 54. 55. }
FactoryBean
MainConfig2
1. @Configuration 2. public class MainConfig2 { 3. 4. 5. /** 6. * 给容器中注册组件; 7. * 1)、包扫描+组件标注注解(@Controller/@Service/@Repository/@Component)[自己写的类] 8. * 2)、@Bean[导入的第三方包里面的组件] 9. * 3)、@Import[快速给容器中导入一个组件] 10. * 1)、@Import(要导入到容器中的组件);容器中就会自动注册这个组件,id默认是全类名 11. * 2)、ImportSelector:返回需要导入的组件的全类名数组; 12. * 3)、ImportBeanDefinitionRegistrar:手动注册bean到容器中 13. * 4)、使用Spring提供的 FactoryBean(工厂Bean); 14. * 1)、默认获取到的是工厂bean调用getObject创建的对象 15. * 2)、要获取工厂Bean本身,我们需要给id前面加一个& 16. * &colorFactoryBean 17. * 18. * 虽然这里装配的是ColorFactoryBean,但实际上beand的类型是Color 19. */ 20. @Bean 21. public ColorFactoryBean colorFactoryBean(){ 22. return new ColorFactoryBean(); 23. } 24. 25. }
ColorFactoryBean
1. //创建一个Spring定义的FactoryBean 2. public class ColorFactoryBean implements FactoryBean<Color> { 3. 4. //返回一个Color对象,这个对象会添加到容器中 5. @Override 6. public Color getObject() throws Exception { 7. // TODO Auto-generated method stub 8. System.out.println("ColorFactoryBean...getObject..."); 9. return new Color(); 10. } 11. 12. @Override 13. public Class<?> getObjectType() { 14. // TODO Auto-generated method stub 15. return Color.class; 16. } 17. 18. //是单例? 19. //true:这个bean是单实例,在容器中保存一份 20. //false:多实例,每次获取都会创建一个新的bean; 21. @Override 22. public boolean isSingleton() { 23. // TODO Auto-generated method stub 24. return false; 25. } 26. 27. }