zoukankan      html  css  js  c++  java
  • Springboot2 注解@Import的使用

            @Import可以导入bean或者@Configuration修饰的配置类。如果配置类在标准的springboot的包结构下,就是SpringbootApplication启动类在包的根目录下,配置类在子包下。就不需要使用@Import导入配置类,如果配置类在第三方的jar下,我们想要引入这个配置类,就需要@Import对其引入到工程中才能生效。因为这个时候配置类不再springboot默认的扫描范围内。

            另外,@Import 相当于Spring xml配置文件中的<import /> 标签。

            下面就看一看@Import的几种用法:

    示例代码:

    使用方法一:导入普通类

    1.1 把普通的类用@Import导入之后成为一个bean。这个类并未使用@Service@Component将其创建为bean

    @Getter
    @Setter
    public class MySqlConn {
        private String driverClass = "xxxx";
        private String url = "jdbc:mysql://localhost:3306/mydb";
        private String userName = "root";
        private String password = "root";
    
    }

    1.2 在springboot的启动类@Import这个类,这个类就可以被其他类当做bean来引用。

    @SpringBootApplication
    @Import({MySqlConn.class})
    public class SpringBootApplication1 {
    
        public static void main(String[] args) {
            SpringApplication.run(SpringBootApplication1.class, args);
        }
    
    }

    1.3 测试,定义一个controller来测试,调用这个通过@Import方式导入的bean

    @RestController
    @RequestMapping("test")
    public class RestTestController {
        @Autowired
        private MySqlConn mySqlConn;
    
        @GetMapping("common")
        public String commonBean() {
            String jsonResult = "";
            ObjectMapper mapper = new ObjectMapper();
            try {
                jsonResult = mapper.writeValueAsString(mySqlConn);
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
            return jsonResult;
        }
    }

    使用方法二:和@Configuration搭配使用

    @Import被用来整合@Configuration注解中定义的bean配置。

    2.1 定义一个配置类@Configuration,配置类中定义了一些bean。下面的代码中可以看到我们定义的beanMySqlServerBean

    @Configuration
    public class MySqlConfig {
        @Bean
        public MySqlServerBean getBean() {
            MySqlServerBean bean = new MySqlServerBean();
            bean.setUserName("lyj");
            return bean;
        }
    }

    2.2 在启动类中@import这个配置类:

    @SpringBootApplication
    @Import(MySqlConfig.class)
    public class SpringBootApplication3 {
        public static void main(String[] args) {
            SpringApplication.run(SpringBootApplication3.class, args);
        }
    }

    2.3 测试,定义一个controller,我们看到在controller中就可以直接使用在MySqlConfig中定义MySqlServerBean了。

    @RestController
    @RequestMapping("test")
    public class RestTestController {
    
        @Autowired
        private MySqlServerBean mySqlServerBean;
    
        @GetMapping("mysql")
        public String mysql() {
            String jsonResult = "";
            ObjectMapper mapper = new ObjectMapper();
            try {
                jsonResult = mapper.writeValueAsString(mySqlServerBean);
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
            return jsonResult;
        }
    }

    使用方法三:在配置类上导入

    在配置类上通过@Import直接导入类,也可以被引用成bean

    3.1 定义一个普通的类

    @Getter
    @Setter
    public class PoolBean {
        private String redisHost = "127.0.0.1";
        private String redisPort = "6379";
        private String redisDb = "0";
    }

    3.2 在配置类上导入这个类

    @Configuration
    @Import({PoolBean.class})
    public class RedisConfig {
        @Bean
        public RedisClusterBean getHost() {
            return new RedisClusterBean();
        }
    }

    3.3 测试,启动项目,在controller直接引用这个PoolBean

    @SpringBootApplication
    public class SpringBootApplication2 {
        public static void main(String[] args) {
            SpringApplication.run(SpringBootApplication2.class, args);
        }
    }
    @RestController
    @RequestMapping("test")
    public class RestTestController {
        @Autowired
        private PoolBean poolBean;
    
        @GetMapping("pool")
        public String poolBean() {
            String jsonResult = "";
            ObjectMapper mapper = new ObjectMapper();
            try {
                jsonResult = mapper.writeValueAsString(poolBean);
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
            return jsonResult;
        }
    
    }

    使用方法四:和ImportSelector搭配使用

    新建一个Maven工程,pom.xml的类型是jar,我们写一个第三方的jar包,用来引用到我们的主工程中,进行ImportSelector的示例使用。工程结构大概如下图:

    4.1 在third-part功能中,我们先定义一个config

    @Configuration
    public class AppConfig {
        @Bean
        public Student studentBean() {
            Student student = new Student();
            student.setId(10);
            student.setName("王某");
            return student;
        }
    }

    4.2 自定义一个SpringStartSelector实现接口ImportSelectorBeanFactoryAware。重写selectImports()方法和setBeanFactory()方法。这里在程序启动的时候会先运行setBeanFactory()方法,我们可以在这里获取到beanFactoryselectImports()方法回了了AppCoinfig的全类名。

    public class SpringStartSelector implements ImportSelector, BeanFactoryAware {
        private BeanFactory beanFactory;
    
        @Override
        public String[] selectImports(AnnotationMetadata importingClassMetadata) {
            System.out.println("importingClassMetaData:" + importingClassMetadata);
            System.out.println("beanFactory:" + beanFactory);
            return new String[]{AppConfig.class.getName()};
        }
    
        @Override
        public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
            this.beanFactory = beanFactory;
        }
    }

    4.3 自定义一个注解EnableSpringStudy,在这个注解使用@Import()导入4.2中自定义的SpringStartSelector

    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Target(ElementType.TYPE)
    @Import(SpringStartSelector.class)
    public @interface EnableSpringStudy {
    }

    4.4 完成之后我们把 third-part项目打成jar包,在主项目pom文件中引入

    <dependency>
        <groupId>com.win.world</groupId>
        <artifactId>third-part</artifactId>
        <version>1.0.0</version>
    </dependency>

    4.5 主项目中在SpringBoot的启动类上使用我们4.3中自定义的注解。然后测试我们能否获取到AppConig中的bean

    @SpringBootApplication
    @EnableSpringStudy
    public class SpringBootApplication4 {
        public static void main(String[] args) {
            SpringApplication.run(SpringBootApplication4.class, args);
        }
    }

    测试能否获取到AppConfig中的bean

    @RestController
    @RequestMapping("test")
    public class RestTestController {
        @Autowired
        private Student student;
    
        @GetMapping("selector")
        public String selector() {
            String jsonResult = "";
            ObjectMapper mapper = new ObjectMapper();
            try {
                jsonResult = mapper.writeValueAsString(student);
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
            return jsonResult;
        }
    
    }

    使用方法五:和ImportBeanDefinitionRegistrar搭配使用

             ImportBeanDefinitionRegistrar接口也是Spring的扩展点之一,它可以支持我们自己写的代码封装成BeanDefinition对象;实现此接口的类回调postProcessBeanDefinitionRegistry方法,注册到Spring容器中。把bean注入到Spring容器不止有@Service @Component 等注解方式,还可以实现此接口。下面看个例子:

    5.1 我们先定义一个MyImportBeanDefinitionRegistrar类实现ImportBeanDefinitionRegistrar接口,并通过重写registerBeanDefinitions()来定义一个bean

    public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar{
        @Override
        public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
            BeanDefinition beanDefinition = new GenericBeanDefinition();
            beanDefinition.setBeanClassName(PoolBean.class.getName());
            MutablePropertyValues property = beanDefinition.getPropertyValues();
            property.addPropertyValue("redisHost", "localhost");
            property.addPropertyValue("redisPort", "6377");
            //这里注册bean
            registry.registerBeanDefinition("poolBean", beanDefinition);
        }
    }

    5.2 定义一个配置类,@Import导入5.1的自定义类

    @Configuration
    @Import(MyImportBeanDefinitionRegistrar.class)
    public class RegistrarConfig {
    }

    5.3 启动项目并测试自己在registerBeanDefinitions()方法中创建的bean PoolBean是否成功

    @SpringBootApplication
    public class SpringBootApplication5 {
        public static void main(String[] args) {
            SpringApplication.run(SpringBootApplication5.class, args);
        }
    }
    @RestController
    @RequestMapping("test")
    public class RestTestController {
        @Autowired
        private PoolBean poolBean;
    
        @GetMapping("registrar")
        public String registrarTest() {
            String jsonResult = "";
            ObjectMapper mapper = new ObjectMapper();
            try {
                jsonResult = mapper.writeValueAsString(poolBean);
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
            return jsonResult;
    
        }
    
    }

    参考:

      【1】Spring框架中@Import注解,https://segmentfault.com/a/1190000011068471

      【2】@Import注解--导入资源,https://blog.csdn.net/u010502101/article/details/78760032

      【3】一分钟学会Spring注解之@Import注解,https://blog.51cto.com/4247649/2118354

           【4】@Import、ImportSelector注解使用及源码分析,https://juejin.im/post/5d63b455f265da03e52341d0

           【5】深入理解Spring的ImportSelector接口,https://www.cnblogs.com/niechen/p/9262452.html

      【6】ImportBeanDefinitionRegistrar, https://blog.csdn.net/baidu_19473529/article/details/90613661

  • 相关阅读:
    1015
    1016
    1014
    1002
    1010
    1006
    动态规划1001
    动态规划1002
    使用EF框架调用带有输出参数(output)的存储过程
    工程地质相关知识
  • 原文地址:https://www.cnblogs.com/happyflyingpig/p/12181569.html
Copyright © 2011-2022 走看看