1. @Configuration, @Bean
@Configuration该注解就是用来告诉spring这是配置类
@Bean该注解是用来注册一个bean。类型是返回值的类型,ID默认是用方法名作为ID的;可以在注解中指定ID,@Bean("person")
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class); //MainConfig.class是配置类 Person bean = applicationContext.getBean(Person.class);
以上注解主要是用来取代了配置文件application.xml中对bean的定义
2. @ComponentScan
该注解用于包扫描,主要是取代了下面的配置。主要扫描标记有以下注解的:@Controller、@Service、@Repository,@Component
<context:component-scan base-package="com.atguigu" use-default-filters="false"></context:component-scan>
属性一:excludeFilters = Filter[] :指定扫描的时候按照什么规则排除那些组件
属性二:includeFilters = Filter[] :指定扫描的时候只需要包含哪些组件;使用该注解需要在配置文件中添加use-default-filters="false",而在注解中,我们需要useDefaultFilters = false;
Java8中@ComponentScan是可以重复使用的,而且也可以使用@ComponentScans注解
@ComponentScans( value = { @ComponentScan(value="com.atguigu",includeFilters = { @ComponentScan.Filter(type= FilterType.ANNOTATION,classes={Controller.class}) /* @Filter(type=FilterType.ASSIGNABLE_TYPE,classes={BookService.class}), @Filter(type= FilterType.CUSTOM,classes={MyTypeFilter.class})*/ },useDefaultFilters = false) } )
3. FilterType
FilterType.ANNOTATION:按照注解
FilterType.ASSIGNABLE_TYPE:按照给定的类型;
FilterType.ASPECTJ:使用ASPECTJ表达式
FilterType.REGEX:使用正则指定
FilterType.CUSTOM:使用自定义规则
4. @scope
prototype:多实例的:ioc容器启动并不会去调用方法创建对象放在容器中。每次获取的时候才会调用方法创建对象;
singleton:单实例的(默认值):ioc容器启动会调用方法创建对象放到ioc容器中。以后每次获取就是直接从容器(map.get())中拿。
5. @Lazy
单实例bean:默认在容器启动的时候创建对象;
懒加载:容器启动不创建对象。第一次使用(获取)Bean创建对象,并初始化;
6.@Conditional
按照一定的条件进行判断,满足条件给容器中注册bean
@Conditional(LinuxCondition.class) 在类中进行条件判断 只有满足条件返回true时才会进行相应的操作,否则不会执行下面的代码。
7. @Import
@Import({Color.class,Red.class,MyImportSelector.class,MyImportBeanDefinitionRegistrar.class})
@Import导入组件,id默认是组件的全类名
ImportSelector:返回需要导入的组件的全类名数组;自定义一个MyImportSelector实现ImportSelector接口。
//返回值,就是到导入到容器中的组件全类名 //AnnotationMetadata:当前标注@Import注解的类的所有注解信息 @Override public String[] selectImports(AnnotationMetadata importingClassMetadata) { //方法不要返回null值,可以返回空的数组 return new String[]{"com.atguigu.bean.Blue","com.atguigu.bean.Yellow"}; }
ImportBeanDefinitionRegistrar:手动注册bean到容器中;自定义MyImportBeanDefinitionRegistrar实现ImportBeanDefinitionRegistrar接口。
/** * AnnotationMetadata:当前类的注解信息 * BeanDefinitionRegistry:BeanDefinition注册类; * 把所有需要添加到容器中的bean;调用 * BeanDefinitionRegistry.registerBeanDefinition手工注册进来 */ @Override public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { //全类名 boolean definition = registry.containsBeanDefinition("com.atguigu.bean.Red"); boolean definition2 = registry.containsBeanDefinition("com.atguigu.bean.Blue"); if(definition && definition2){ //指定Bean定义信息;(Bean的类型,Bean。。。) RootBeanDefinition beanDefinition = new RootBeanDefinition(RainBow.class); //注册一个Bean,指定bean名 registry.registerBeanDefinition("rainBow", beanDefinition); } }
8. 工厂bean
自定义工厂bean实现spring的接口FactoryBean
1)默认获取到的是工厂bean调用getObject创建的对象,而不是工厂bean本身;
//工厂Bean获取的是调用getObject创建的对象 获取的是color bean对象 Object bean2 = applicationContext.getBean("colorFactoryBean");
2)要获取工厂Bean本身,我们需要给id前面加一个&
Object bean4 = applicationContext.getBean("&colorFactoryBean");
9. @bean的声明周期配置类
1)初始化的一些配置
1.1)、指定初始化和销毁方法;
通过@Bean指定init-method和destroy-method;
@Bean(initMethod="init",destroyMethod="detory")
1.2)、通过让Bean实现InitializingBean(定义初始化逻辑),
DisposableBean(定义销毁逻辑);
1.3)、可以使用JSR250;
@PostConstruct:在bean创建完成并且属性赋值完成;来执行初始化方法
@PreDestroy:在容器销毁bean之前通知我们进行清理工作
1.4)、BeanPostProcessor【interface】:bean的后置处理器;
在bean初始化前后进行一些处理工作;
postProcessBeforeInitialization:在初始化之前工作
postProcessAfterInitialization:在初始化之后工作
2)bean的生命周期:
2.1)构造(对象创建)
单实例:在容器启动的时候创建对象 多实例:在每次获取的时候创建对象
2.2)BeanPostProcessor.postProcessBeforeInitialization
2.3)初始化:对象创建完成,并赋值好,调用初始化方法。。。
2.4)BeanPostProcessor.postProcessAfterInitialization
2.5)销毁:
单实例:容器关闭的时候 多实例:容器不会管理这个bean;容器不会调用销毁方法;
3)BeanPostProcessor原理
遍历得到容器中所有的BeanPostProcessor;挨个执行beforeInitialization,一但返回null,跳出for循环,不会执行后面的BeanPostProcessor.postProcessorsBeforeInitialization
3.1)populateBean(beanName, mbd, instanceWrapper);//给bean进行属性赋值 3.2)initializeBean { 3.3) applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); 3.4) invokeInitMethods(beanName, wrappedBean, mbd);执行自定义初始化 3.5) applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); }
3)Spring底层对BeanPostProcessor的使用
bean赋值,注入其他组件,@Autowired,生命周期注解功能,@Async,xxx BeanPostProcessor;
10.@Value @PropertySource
1)、基本数值
@Value("张三")
2)、可以写SpEL; #{}
@Value("#{20-2}")
3)、可以写${};取出配置文件【properties】中的值(在运行环境变量里面的值)---大括号中写的是配置文件中的key。
//使用@PropertySource读取外部配置文件中的k/v保存到运行的环境变量中;加载完外部的配置文件以后使用${}取出配置文件的值 @PropertySource(value={"classpath:/person.properties"}) @Configuration public class MainConfigOfPropertyValues { @Bean public Person person(){ return new Person(); } }
@Value("${person.nickName}") private String nickName;
也可以通过以下的方式获取配置文件中值
ConfigurableEnvironment environment = applicationContext.getEnvironment(); String property = environment.getProperty("person.nickName"); System.out.println(property);
11. 自动装配
Spring利用依赖注入DI,完成对IOC容器中各个组件赋值;
1-->@Autowired 自动注入--spring的
1)默认按照类型去容器中找对应的组件:applicationContext.getBean(BookDao.class);找到就赋值
2)如果找到多个相同类型的组件,在将属性的名称作为ID去容器中查找applicationContext.getBean("bookDao2") @Autowired private BookDao bookDao2;---这里的bookDao2
3)@Qualifier("bookDao"):使用@Qualifier指定需要装配的id,而不是属性名;
4)自动装配默认一定要将属性赋值好,没有就会报错可以使用@Autowired(required=false);在没有的情况下也不会报错
5)@Primary:让Spring进行自动装配的时候,默认使用首选的bean;也可以使用@Qualifier指定需要装配的bean的名字
1.1-->@Autowired
@Autowired可以标注在构造器,参数,方法,属性上;都是从容器中获取组件的值
1)标注在方法位置
//@Autowired //标注在方法,Spring容器创建当前对象,就会调用方法,完成赋值; //方法使用的参数,自定义类型的值从ioc容器中获取 public void setCar(Car car) { this.car = car; }
2)标注在构造器位置--如果组件只有一个有参构造器,这个有参构造器的 @Autowired可以省略,参数位置的组件还是可以从容器中自动获取
//默认加在ioc容器中的组件,容器启动会调用无参构造器创建对象,再进行初始化赋值等操作 //构造器要用的组件,都是从容器中获取 @Autowired public Boss(Car car){ this.car = car; System.out.println("Boss...有参构造器"); }
2-->@Resource 自动注入--Java规范
默认是按照属性名称注入的@Resource(name="bookDao2") 不指定名字就是属性的名字。他是Java规范中的,它不支持@Primary和@Autowired(required=false)
3-->@Inject 自动注入--Java规范
它的功能和Autowired的是一样的,但是需要导入依赖包,其次他没有@Autowired(required=false)功能
4-->自定义组件 注入到bean中
如果自定义组件想要使用spring容器底层的一些组件,如applicationContext,BeanFactory...;自定义组件实现XXXAware;在创建对象的时候会调用规定的方法注入相关的组件---将spring底层的组件装配到自定义的bean中
XXXAware的功能都是使用XXXProcessor来处理的。
@Component public class Red implements ApplicationContextAware,BeanNameAware,EmbeddedValueResolverAware { private ApplicationContext applicationContext; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { // TODO Auto-generated method stub System.out.println("传入的ioc:"+applicationContext); this.applicationContext = applicationContext; } @Override public void setBeanName(String name) { // TODO Auto-generated method stub System.out.println("当前bean的名字:"+name); } //StringValueResolver重要 @Override public void setEmbeddedValueResolver(StringValueResolver resolver) { // TODO Auto-generated method stub String resolveStringValue = resolver.resolveStringValue("你好 ${os.name} 我是 #{20*18}"); System.out.println("解析的字符串:"+resolveStringValue); } }
5-->@Profile 自动装配
Spring为我们提供的可以根据当前环境,动态的激活和切换一系列组件的功能;指定组件在哪个环境的情况下才能被注册到容器中,不指定,任何环境下都能注册这个组件
1)加了环境标识的bean,只有这个环境被激活的时候才能注册到容器中。默认是default环境
@Profile("default")
2)@Profile写在配置类上,只有是指定的环境的时候,整个配置类里面的所有配置才能开始生效.
即写在配置类上的@Profile中的属性必须在需要激活的环境中存在,然后按照需要激活的环境来加载bean
3)没有标注环境标识的bean在任何环境下都是加载的;
方式一:(test是指@Profile中ID值) 使用命令行动态参数: 在虚拟机参数位置加载 -Dspring.profiles.active=test 方式二:(不能使用有参构造器启动) AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(); //1、创建一个applicationContext //2、设置需要激活的环境 applicationContext.getEnvironment().setActiveProfiles("test","dev"); //3、注册主配置类 applicationContext.register(MainConfigOfProfile.class); //4、启动刷新容器 applicationContext.refresh(); String[] namesForType = applicationContext.getBeanNamesForType(DataSource.class); for (String string : namesForType) { System.out.println(string); } // Yellow bean = applicationContext.getBean(Yellow.class); // System.out.println(bean); applicationContext.close();
12. 小结
组件添加:++@Import @Conditional++ @Configuration @Bean @ComponentScan @scope @Lazy @Controller @Service @Repository @Component @Primary 工厂模式
组件赋值:@Value @PropertySource @PropertySources @Autowired )@Qualifier @Resource @Inject @Profile
组件注入:方法参数,构造器注入,applicationContextAware(xxxAware)
来源:https://www.cnblogs.com/ntbww93/p/10091846.html