上一节:SpringBoot开发笔记-(4) 属性文件读取2: @PropertySource


5.1 前情提要-场景

之前的2节都是讲怎么读取配置文件; 然而如果有下列的状况, 就须要用到@ImportResource来帮忙了:

  1. 有一个遗留的xml文件, 比方名叫 spring-beans.xml 外面有很多的配置bean, 都须要注册到spring容器中, 让容器来治理这些bean以备不时之需;
  2. 传统springmvc的我的项目, 原来的xml配置文件不想删除, 然而又想用springboot来革新它; 就能够应用 @ImportResource来 导入内部资源

简言之: 就是还想用xml, 还想用 springboot; xml就由此注解来注册进去!

5.2. 示例

  1. 启动类上加注解: @ImportResource("classpath:/spring/spring-*.xml")
package com.niewj.springboot;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.context.annotation.ImportResource;@SpringBootApplication@ImportResource("classpath:/spring/spring-*.xml")public class HelloApplication {    public static void main(String[] args) {        SpringApplication.run(HelloApplication.class, args);    }}
  1. resource: spring/spring-html.xml文件:
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"      xsi:schemaLocation="http://www.springframework.org/schema/beans      http://www.springframework.org/schema/beans/spring-beans.xsd">   <!-- -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -->   <!-- RestTemplate -->   <bean id="httpClient" class="com.niewj.springboot.utils.MyHttpClientUtils" factory-method="buildHttpClient"/>   <bean id="clientHttpRequestFactory" class="org.springframework.http.client.HttpComponentsClientHttpRequestFactory">       <property name="connectTimeout" value="20000"/><!-- 连贯超时 -->       <property name="readTimeout" value="30000"/><!-- 数据读取超时工夫 -->       <property name="connectionRequestTimeout" value="20000"/> <!-- 连贯不够用的等待时间 -->       <constructor-arg ref="httpClient"/>   </bean>   <bean id="restTemplate" class=" org.springframework.web.client.RestTemplate">       <constructor-arg ref="clientHttpRequestFactory"/>   </bean></beans>

这个xml中心愿失去一个 RestTemplate的bean, 须要依赖一个httpClient, httpClient代码咱们本人写的, 如下:

package com.niewj.springboot.utils;import org.apache.http.config.Registry;import org.apache.http.config.RegistryBuilder;import org.apache.http.conn.socket.ConnectionSocketFactory;import org.apache.http.conn.socket.PlainConnectionSocketFactory;import org.apache.http.conn.ssl.NoopHostnameVerifier;import org.apache.http.conn.ssl.SSLConnectionSocketFactory;import org.apache.http.conn.ssl.TrustStrategy;import org.apache.http.impl.client.CloseableHttpClient;import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;import org.apache.http.impl.client.HttpClientBuilder;import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;import org.apache.http.ssl.SSLContextBuilder;import javax.net.ssl.HostnameVerifier;import javax.net.ssl.SSLContext;import java.security.KeyManagementException;import java.security.KeyStoreException;import java.security.NoSuchAlgorithmException;import java.security.cert.CertificateException;import java.security.cert.X509Certificate;/** * Created by niewj on 2019/04/10. */public class MyHttpClientUtils {    public static CloseableHttpClient buildHttpClient() throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException {        HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();        // setup a Trust Strategy that allows all certificates.        //        SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {            @Override            public boolean isTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {                return true;            }        }).build();        httpClientBuilder.setSSLContext(sslContext);        HostnameVerifier hostnameVerifier = NoopHostnameVerifier.INSTANCE;        // 这是非凡的局部:        //      -- need to create an SSL Socket Factory, to use our weakened "trust strategy";        //      -- and create a Registry, to register it.        //        SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContext, hostnameVerifier);        // 注册http和https申请        Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()                .register("http", PlainConnectionSocketFactory.getSocketFactory())                .register("https", sslSocketFactory).build();        // 开始设置连接池-- allows multi-threaded use        PoolingHttpClientConnectionManager connMgr = new PoolingHttpClientConnectionManager(socketFactoryRegistry);        // 最大连接数200        connMgr.setMaxTotal(200);        // 同路由并发数100        connMgr.setDefaultMaxPerRoute(100);        httpClientBuilder.setConnectionManager(connMgr);        // 重试次数        httpClientBuilder.setRetryHandler(new DefaultHttpRequestRetryHandler(3, true));        CloseableHttpClient client = httpClientBuilder.build();        return client;    }}

在此例中, 这个类自身并不重要, 重要的是 xml中配置的bean id, 要最终在spring容器中可能检索到, 拿出对象;

测试用例:

package com.niewj.springboot;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.test.context.SpringBootTest;import org.springframework.context.ApplicationContext;import org.springframework.test.context.junit4.SpringRunner;import org.springframework.web.client.RestTemplate;import java.util.Arrays;import java.util.Optional;@RunWith(SpringRunner.class)@SpringBootTestpublic class SpringbootTest {    @Autowired    private ApplicationContext ctx;    @Test    public void testImportResurce() {        // 从spring容器中拿到容器治理的所有bean定义, 而后过滤 bean的id, 看有没有叫 restTemplate的:        Optional<String> restTemplate = Arrays.stream(ctx.getBeanDefinitionNames()).filter(s -> s.equalsIgnoreCase("restTemplate")).findAny();        String template = restTemplate.orElse(null);        // 如果有, 打印出对象        if(null != template){            System.out.println(ctx.getBean(RestTemplate.class));        }    }}

输入:

org.springframework.web.client.RestTemplate@2dd8239

如果把 @ImportResource这一行正文掉: 就什么都不会输入了!!!

package com.niewj.springboot;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.context.annotation.ImportResource;@SpringBootApplication//@ImportResource("classpath:/spring/spring-*.xml")public class HelloApplication {    public static void main(String[] args) {        SpringApplication.run(HelloApplication.class, args);    }}

5.3 小结@ImportResource

  1. 作用: 想容器中注册 xml模式的bean;
  2. @Import也能够将无注解的纯pojo Bean放入到spring容器中; @ImportResource是放入xml文件, 留神区别;

    @Import参见: spring注解驱动开发-(5) 向Spring容器中注册组件的办法