栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

五、Spring注解开发IOC

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

五、Spring注解开发IOC

五、Spring注解开发 1、Spring注解开发概述
  • Spring是轻代码重配置的框架,配置比较繁重,影响开发效率
  • 注解代替xml配置文件可以简化配置,提高开发效率,注解开发是一种趋势
  • SpringBoot中使用的即为注解开发
2、@Configuration用来代替xml配置文件
@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();
      	}
      
4、按需加载@Conditional注解
  • 满足条件给容器中注册Bean,SpringBoot中十分常见

  • 实现 Condition 接口 重写matches() 方法

    boolean matches(ConditionContext context, AnnotatedTypemetadata metadata){
        //ConditionContext : 判断条件时能使用的上下文环境
        //AnnotatedTypemetadata: 标注了@Condition注解的类的注释信息
        //进行条件判断返回true则 : 注入 返回false则: 不注入
    }
    
5、@ComponentScan注解
@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;
        }
    }
    
7、@Value注解

@Value中的值可以有

  1. 基本数值
  2. #{}
  3. ${} ,取出配置文件中的值(在运行环境变量中的值)
8、@PropertySource注解
  • 该注解可以将配置文件加载到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);
          }
      
9、自动注入
  • @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注解可以标注的位置 : 参数,方法,属性 (都是从容器中获取参数组件的值)

    1. 标注在方法上 : @Bean + 方法参数,@Bean标注的方法形参是可以省略@Autowired的
    2. 标注在构造器上 : 如果组件只有一个有参构造器,参数位置上的@Autowired注解是可以省略的
    3. 放在参数位置上 : 按照逻辑,要注入组件进去,传递参数,参数也一定是要注入的,所以@Autowired标注在参数位置上,但是通常省略
  • 自定义的组件使用Spring容器底层的一些组件,例如(ApplicationContext,BeanFactory)

    • 自定义组件时实现xxxAware接口即可,在创建对象的时候,会调用接口规定的方法注入相关组件:Aware吧Spring底层的一些组件注册到自定义的Bean中

    • xxxAware: 都会使用后置处理器 xxxProcessor,每一个xxxAware都会对应一个xxxProcessor,例如:

      ApplicationContextAware 对应一个 ApplicationContextAwareProcessor

10、指定环境@Profile注解
  • @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

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/346172.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号