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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM