关于springboot:SpringBoot开发笔记5导入外部资源-ImportResource

7次阅读

共计 5777 个字符,预计需要花费 15 分钟才能阅读完成。

上一节: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)
@SpringBootTest
public 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 容器中注册组件的办法

正文完
 0