- Spring是轻代码重配置的框架,配置比较繁重,影响开发效率
- 注解代替xml配置文件可以简化配置,提高开发效率,注解开发是一种趋势
- SpringBoot中使用的即为注解开发
@Configuration//标志这是一个配置类
//@ComponentScan(value = {"day01"})//用来代替 标签
public class SpringConfig {
@Scope("prototype")//用来代替 bean标签中的prototype中的scope属性,同样prototype是在每次获取bean对象的时候就会调用一次
//@Lazy对于scope标志注解的时候使用懒加载,不在容器启动的时候就注册bean
@Bean//用来代替标签
public Person person(){
Person person = new Person();
person.setName("张三");
person.setAge(21);
return person;
}
}
3、组件注册的方式
-
包扫描 + 组件标注注解(@Controller 、@Service 、@Repository 、@Component)
- 这四个注解只适用于自己写的类,或者已经标注该注解的类能注册组件
-
@Bean注解
- 通过标注在方法上,可以将单个组件添加到容器中,可以导入第三方里面的组件
-
@import注解(快速给容器中导入一个组件(一次可以导入多个))
-
@import(要导入到容器中的组件) : 可以是一个数组,自动注册这些组件,id默认是全类名
-
importSelector : 实现importSelector接口的方法需要导入组件的全类名数组
public class MyimportSelector implements importSelector { @Override public String[] selectimports(Annotationmetadata importingClassmetadata) { //返回的数组,将会注册为组件 String[] comp = new String[]{"day01.Person"}; return comp; } }@import(MyimportSelector.class)//导入自己编写的importSelector类 public class SpringConfig { //配置类 } -
importBeanDefinitionRegistrar : 手动注册Bean到容器中需要实现importBeanDefinitionRegistrar接口
-
-
使用Spring提供的 FactoryBean(工厂Bean)配合@Bean注解
-
默认获取到的是工厂Bean调用getObject()方法创建的对象
-
若要获取工厂Bean本身,我们需要给id前面加上一个 & 即&courseFactory
-
即是这样:
@Test public void test2(){ ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class); CourseFactory course = (CourseFactory)context.getBean("&courseFactory"); }
-
-
实现Factorybean接口
public class CourseFactory implements FactoryBean
{ //用来返回对象 @Override public Course getObject() throws Exception { Course course = new Course(); course.setName("一本书"); return course; } //返回类型 @Override public Class> getObjectType() { return null; } //标注在IOC容器中是否是单例的 //true : 单例 false : 多例的 @Override public boolean isSingleton() { return false; } } @Bean public CourseFactory colorFactoryBean(){ return new CourseFactory(); }
-
-
满足条件给容器中注册Bean,SpringBoot中十分常见
-
实现 Condition 接口 重写matches() 方法
boolean matches(ConditionContext context, AnnotatedTypemetadata metadata){ //ConditionContext : 判断条件时能使用的上下文环境 //AnnotatedTypemetadata: 标注了@Condition注解的类的注释信息 //进行条件判断返回true则 : 注入 返回false则: 不注入 }
@ComponentScan(
value = {"day01"},
excludeFilters = {
@ComponentScan.Filter(
type = FilterType.ANNOTATION,classes = {Controller.class}),
@ComponentScan.Filter(
type = FilterType.CUSTOM,classes = {MyTypeFilter.class}
)})
//用来代替 标签
//若要实现只包含那个注解标注的则需要配置这个属性use-default-filters="false"
//excludeFilters = Filter[]
//includeFilters = Filter[]
//FilterType.ANNOTATION : 按照注解
//FilterType.ASSIGNABLE_TYPE : 按照给定的方式
//FilterType.ASPECTJ : 使用aspectj表达式
//FilterType.REGEX : 使用正则指定
//FilterType.CUSTOM : 使用自定义规则
@import(MyimportSelector.class)
public class SpringConfig {
}
6、初始化和销毁方法
-
方式一:
-
通过@Bean指定initMethod和destoryMethod属性
@Bean(initMethod = "init",destroyMethod = "destory")
-
-
方式二:
-
让Bean实现InitializingBean接口和DisposableBean接口重写接口中的方法
public class Person implements InitializingBean, DisposableBean { @Override public void destroy() throws Exception { //实现DisposableBean接口的销毁方法,销毁逻辑 } @Override public void afterPropertiesSet() throws Exception { //实现InitializingBean接口的初始化方法,初始化逻辑 } }
-
-
方式三:@PostConstruct 和 @PreDestory注解 但是这两个注解是javax.包下的,并不是Spring中的
public class Person{ @PostConstruct public void init(){ //在构造器执行后,属性赋值之后执行 } @PreDestroy public void destroy(){ //在容器销毁前执行 } } -
方式四:Bean的后置处理器BeanPostProcessor只需要在将BeanPost配置到容器中即可
public class BeanPost implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("第三步:我在bean初始化方法前执行,Bean的后置处理器"); return null; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("第五步:我在bean初始化方法后执行,bean的后置处理器"); return null; } }
@Value中的值可以有
- 基本数值
- #{}
- ${} ,取出配置文件中的值(在运行环境变量中的值)
-
该注解可以将配置文件加载到ioc容器中
-
获取配置文件中属性的方法有两种
-
方式一:使用${key} 将 value取出来
-
方式二:获取环境变量的方法再获取(配置文件中的值默认都会加载到环境变量中去)
@Test public void test2(){ ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class); //通过context获取上下文环境 Environment environment = context.getEnvironment(); //getProperty(key)获取value String keyValue = environment.getProperty("key"); System.out.println(keyValue); }
-
-
@Autowired注解:
- 默认优先按照类型去容器中寻找响应的组件,调用:context.getBean(BookDao.class)方法
- 如果找到多个相同类型的组件,再将属性的名称作为组件的id去容器中查找,调用context.getBean(“bookDao”)方法
- @Qualifier(“bookDao”) : 使用@Qualifier指定需要装配的组件id,而不是使用属性名
- 自动装配默认bean的属性一定要赋值完成,否则包异常,可以指定@Autowired(required=false)注解来实现可以不将属性赋值完成
- @Primary : 该注解可以让Spring进行自动装配的时候,默认优先选择标注该注解的Bean,当然后面可以使用@Qualifier注解指定
-
@Resource注解:
- 也可以实现自动装配,但是默认是按照组件名称装配的,不支持@Primary注解功能,javax中的注解
-
@Inject注解:
- 也可以实现自动装配支持@Primary注解功能,但不支持required=false功能,javax中的注解,还需要导包javax Inject的jar包
-
@Autowired注解可以标注的位置 : 参数,方法,属性 (都是从容器中获取参数组件的值)
- 标注在方法上 : @Bean + 方法参数,@Bean标注的方法形参是可以省略@Autowired的
- 标注在构造器上 : 如果组件只有一个有参构造器,参数位置上的@Autowired注解是可以省略的
- 放在参数位置上 : 按照逻辑,要注入组件进去,传递参数,参数也一定是要注入的,所以@Autowired标注在参数位置上,但是通常省略
-
自定义的组件使用Spring容器底层的一些组件,例如(ApplicationContext,BeanFactory)
-
自定义组件时实现xxxAware接口即可,在创建对象的时候,会调用接口规定的方法注入相关组件:Aware吧Spring底层的一些组件注册到自定义的Bean中
-
xxxAware: 都会使用后置处理器 xxxProcessor,每一个xxxAware都会对应一个xxxProcessor,例如:
ApplicationContextAware 对应一个 ApplicationContextAwareProcessor
-
-
@Profile注解指定组件在哪个环境的情况下才能注册到容器中,不指定@Profile的组件,在任何环境下都能注册这个组件
- 标注在@Bean方法上,只有这个环境被激活的时候才能注册到容器中,默认是default环境
- 标注在配置类上,只有是指定环境的时候,真个配置类里面的所有配置才能开始生效
-
运行的时候如何指定环境
-
方式一:在虚拟机参数位置传入参数 : -Dspring.profiles.active=test
指定环境为test测试环境
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-anmbQdjq-1635082780147)(C:UsersAdministrator.DESKTOP-O7Q3NEAAppDataRoamingTyporatypora-user-imagesimage-20211022185909224.png)]
-
方式二:不使用有参构造器获取ApplicationContext对象,使用无参构造器
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1A9Q2EJe-1635082780151)(C:UsersAdministrator.DESKTOP-O7Q3NEAAppDataRoamingTyporatypora-user-imagesimage-20211022191111150.png)]
-
default环境
-
标注在配置类上,只有是指定环境的时候,真个配置类里面的所有配置才能开始生效
-
运行的时候如何指定环境
-
方式一:在虚拟机参数位置传入参数 : -Dspring.profiles.active=test
指定环境为test测试环境
[外链图片转存中…(img-anmbQdjq-1635082780147)]
-
方式二:不使用有参构造器获取ApplicationContext对象,使用无参构造器
[外链图片转存中…(img-1A9Q2EJe-1635082780151)]
注:在Spring5中已经全部重写,已经没有这些方法了,上述方式二仅仅适用于Spring4
-



