<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>spring boot &#8211; 有意与无意之间</title>
	<atom:link href="https://zhangxihai.cn/archives/tag/spring-boot/feed" rel="self" type="application/rss+xml" />
	<link>https://zhangxihai.cn</link>
	<description>千淘万漉虽辛苦 吹尽狂沙始到金 - 生命不息 编程不止</description>
	<lastBuildDate>Thu, 16 May 2024 08:58:48 +0000</lastBuildDate>
	<language>zh-CN</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.0.11</generator>
	<item>
		<title>Spring Boot: AutoConfigurationImportFilter过滤器</title>
		<link>https://zhangxihai.cn/archives/350</link>
					<comments>https://zhangxihai.cn/archives/350#respond</comments>
		
		<dc:creator><![CDATA[胖爷]]></dc:creator>
		<pubDate>Mon, 09 Apr 2018 05:47:40 +0000</pubDate>
				<category><![CDATA[编码]]></category>
		<category><![CDATA[spring boot]]></category>
		<category><![CDATA[过滤器]]></category>
		<guid isPermaLink="false">https://zhangxihai.cn/?p=350</guid>

					<description><![CDATA[在Spring Boot中，AutoConfigurationImportFilter是一个接口，用于控制自动配置类的导入过程，从而影响应用程序的自动配置过程，它的作用和原理是允许开发者通过自定义过滤器来决定哪些自动配置类应该被包含或排除，以达到更灵活第管理自动配置的目的。 作用 过滤自动配置类 允许开发者根据特定条件过滤掉不需要的自动配置类，从而精确控制应...]]></description>
										<content:encoded><![CDATA[<p>在Spring Boot中，<code>AutoConfigurationImportFilter</code>是一个接口，用于控制自动配置类的导入过程，从而影响应用程序的自动配置过程，它的作用和原理是允许开发者通过自定义过滤器来决定哪些自动配置类应该被包含或排除，以达到更灵活第管理自动配置的目的。</p>
<h3>作用</h3>
<ol>
<li>
<p><strong>过滤自动配置类</strong> 允许开发者根据特定条件过滤掉不需要的自动配置类，从而精确控制应用程序的配置;</p>
</li>
<li>
<p><strong>解决冲突</strong> 当某些自动配置类与应用中其他配置发生冲突时，可以通过自定义过滤器来排除冲突的自动配置类；</p>
</li>
<li>
<p><strong>提高启动性能</strong> 排除不需要的自动配置类可以减少应用程序的启动时间，提高应用的性能。</p>
</li>
</ol>
<p><code>AutoConfigurationImportFilter</code>接口的实现类会在Spring Boot应用启动时被Spring Boot框架调用。框架会遍历所有的<code>spring.factories</code>文件中定义的<code>AutoConfigurationImportFilter</code>实现类，并调用它们的<code>match</code>方法。在该方法中，开发者可以根据自定义的逻辑来决定是否包含或排除特定的自动配置类。最终，只有符合过滤条件的自动配置类才会被导入到应用程序的Spring上下文中。</p>
<p>使用方法：</p>
<h4>1 自定义过滤器</h4>
<p><code>MyAutoConfigurationFilter.java</code></p>
<pre><code class="language-java">import org.springframework.boot.autoconfigure.AutoConfigurationImportFilter;
import org.springframework.boot.autoconfigure.AutoConfigurationMetadata;

public class MyAutoConfigurationFilter implements AutoConfigurationImportFilter {

    @Override
    public boolean[] match(String[] autoConfigurationClasses, AutoConfigurationMetadata metadata) {
        boolean[] matches = new boolean[autoConfigurationClasses.length];
        for (int i = 0; i &lt; autoConfigurationClasses.length; i++) {
            String autoConfigurationClass = autoConfigurationClasses[i];
            // 根据自定义的条件判断是否需要排除该自动配置类
            if (autoConfigurationClass.equals(&quot;org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration&quot;)) {
                matches[i] = false; // 排除 DataSourceAutoConfiguration
            } else {
                matches[i] = true;
            }
        }
        return matches;
    }
}</code></pre>
<h4>2 在<code>spring.factories</code>中配置过滤器</h4>
<p>在<code>META-INF/spring.factories</code>文件中配置自定义的过滤器。<br />
<code>META-INF/spring.factories</code></p>
<pre><code class="language-java">org.springframework.boot.autoconfigure.AutoConfigurationImportFilter=com.example.demo.MyAutoConfigurationFilter
</code></pre>
<h4>3 应用启动类</h4>
<p><code>MyApplication.java</code></p>
<pre><code class="language-java">import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class MyApplication {
    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }
}</code></pre>
]]></content:encoded>
					
					<wfw:commentRss>https://zhangxihai.cn/archives/350/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Spring Boot: TypeExcludeFilter过滤器</title>
		<link>https://zhangxihai.cn/archives/346</link>
					<comments>https://zhangxihai.cn/archives/346#respond</comments>
		
		<dc:creator><![CDATA[胖爷]]></dc:creator>
		<pubDate>Sun, 08 Apr 2018 09:09:28 +0000</pubDate>
				<category><![CDATA[编码]]></category>
		<category><![CDATA[spring boot]]></category>
		<category><![CDATA[过滤器]]></category>
		<guid isPermaLink="false">https://zhangxihai.cn/?p=346</guid>

					<description><![CDATA[在Spring Boot中，TypeExcludeFilter是@CommonentScan注解设定的两个默认过滤器中的一个。 TypeExcludeFilter是Spring boot提供的一种机制，用于在测试中排除某些类型的Bean。这在大型应用程序中非常有用，可以防止某些bean在测试中被加载，从而加快测试速度或比年冲突。 使用方法： 1 创建一个自定...]]></description>
										<content:encoded><![CDATA[<p>在Spring Boot中，<code>TypeExcludeFilter</code>是<code>@CommonentScan</code>注解设定的两个默认过滤器中的一个。</p>
<p><code>TypeExcludeFilter</code>是Spring boot提供的一种机制，用于在测试中排除某些类型的Bean。这在大型应用程序中非常有用，可以防止某些bean在测试中被加载，从而加快测试速度或比年冲突。</p>
<p>使用方法：</p>
<h3>1 创建一个自定义的<code>TypeExcludeFilter</code></h3>
<p><code>MyTypeExcludeFilter.java</code>这个过滤器将制定哪些类型的bean应该被排除。</p>
<pre><code>import org.springframework.boot.context.TypeExcludeFilter;
import org.springframework.core.type.AnnotatedTypeMetadata;
import org.springframework.stereotype.Component;

@Component
public class MyTypeExcludeFilter extends TypeExcludeFilter {

    @Override
    public boolean match(AnnotatedTypeMetadata metadata) {
        // 在这里定义需要排除的bean的逻辑
        String className = metadata.getClassName();
        // 例如，排除所有 MyExcludedService 类型的 bean
        return className.equals(&quot;com.example.demo.MyExcludedService&quot;);
    }
}</code></pre>
<h3>2 创建要排除的服务类</h3>
<p>创建一个简单的服务类，该服务类将在测试中被排除。</p>
<p><code>MyExcludedService.java</code></p>
<pre><code class="language-java">package com.example.demo;

import org.springframework.stereotype.Service;

@Service
public class MyExcludedService {
    public void doSomething() {
        System.out.println(&quot;This service should be excluded in tests.&quot;);
    }
}</code></pre>
<h3>3 在测试中使用自定义的<code>TypeExcludeFilter</code></h3>
<p>在测试类中，我们需要将自定义的<code>TypeExcludeFilter</code>注册到Spring Boot测试上下文中。</p>
<p><code>MyApplicationTests.java</code></p>
<pre><code class="language-java">package com.example.demo;

import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.FilterType;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.boot.test.autoconfigure.filter.TypeExcludeFilters;

@SpringBootTest
@ContextConfiguration(classes = MyApplication.class)
@TypeExcludeFilters(MyTypeExcludeFilter.class)
public class MyApplicationTests {

    @Test
    public void contextLoads() {
        // 测试内容
    }
}</code></pre>
<h3>4 代码结构</h3>
<pre><code>src
├── main
│   └── java
│       └── com
│           └── example
│               └── demo
│                   ├── MyApplication.java
│                   ├── MyExcludedService.java
│                   └── MyTypeExcludeFilter.java
└── test
    └── java
        └── com
            └── example
                └── demo
                    └── MyApplicationTests.java</code></pre>
<p><code>MyApplication.java</code></p>
<pre><code class="language-java">package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class MyApplication {
    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }
}</code></pre>
<h3>5 测试</h3>
<p>当运行 <code>MyApplicationTests</code> 时，<code>MyExcludedService</code> 将不会被加载到 Spring 上下文中。这可以通过在 <code>MyExcludedService</code> 中添加一些输出语句并观察控制台输出来验证。</p>
<p>使用 <code>TypeExcludeFilter</code> 可以在测试中排除特定类型的 bean，从而简化测试环境，减少不必要的依赖，提高测试的速度和稳定性。通过自定义 <code>TypeExcludeFilter</code>，可以灵活地控制哪些 bean 需要被排除，非常适合复杂的应用场景。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://zhangxihai.cn/archives/346/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Spring Boot: ImportSelector接口</title>
		<link>https://zhangxihai.cn/archives/342</link>
					<comments>https://zhangxihai.cn/archives/342#respond</comments>
		
		<dc:creator><![CDATA[胖爷]]></dc:creator>
		<pubDate>Sun, 08 Apr 2018 03:50:44 +0000</pubDate>
				<category><![CDATA[编码]]></category>
		<category><![CDATA[spring]]></category>
		<category><![CDATA[spring boot]]></category>
		<guid isPermaLink="false">https://zhangxihai.cn/?p=342</guid>

					<description><![CDATA[在Spring Boot中，ImportSelector是一个允许动态选择和导入配置类的接口，它的主要作用是根据某些条件动态决定哪些配资类需要被导入Spring应用的上下文中。 接口定义 public interface ImportSelector { String[] selectImports(AnnotationMetadata importingC...]]></description>
										<content:encoded><![CDATA[<p>在Spring Boot中，<code>ImportSelector</code>是一个允许动态选择和导入配置类的接口，它的主要作用是根据某些条件动态决定哪些配资类需要被导入Spring应用的上下文中。</p>
<h3>接口定义</h3>
<pre><code>public interface ImportSelector {
    String[] selectImports(AnnotationMetadata importingClassMetadata);
}</code></pre>
<p><strong>参数AnnotationMetadata</strong>：表示使用了<code>@Import</code>注解的类的元数据，方法返回一个字符串数组，每个字符串对应一个需要导入的配置类的全限定名。</p>
<p><strong>作用过程</strong> 当Spring boot启动时，它会扫描到使用了<code>@Import</code>注解的类，<code>ImportSelector</code>会根据传入的元数据决定需要导入的配置类，并将这些类注册到Spring上下文中。</p>
<p><strong>应用场景</strong> </p>
<ol>
<li>当基于条件(如环境变量、JVM系统属性等)动态导入配置类时；</li>
<li>在创建自定义的启动注解（如<code>@EnableSomeFuture</code>）时，通过<code>ImportSelector</code>来导入现骨干的配置类；</li>
<li>Spring框架本身在多个地方使用<code>ImportorSelector</code>来简化客户端的配置负担，如<code>@EnableAsync</code>、<code>@EnableScheduling</code>。</li>
</ol>
<p>示例</p>
<pre><code>import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.type.AnnotationMetadata;

public class MyImportSelector implements ImportSelector {
    @Override
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        // 基于条件选择配置类
        String prop = System.getProperty(&quot;myProp&quot;);
        if (&quot;someValue&quot;.equals(prop)) {
            return new String[]{MyConfig1.class.getName()};
        } else {
            return new String[]{MyConfig2.class.getName()};
        }
    }
}

@Configuration
public class MyConfig1 {
    @Bean
    public AppBean appBean() {
        return new AppBean(&quot;from config 1&quot;);
    }
}

@Configuration
public class MyConfig2 {
    @Bean
    public AppBean appBean() {
        return new AppBean(&quot;from config 2&quot;);
    }
}

public class AppBean {
    private String message;
    public AppBean(String message) {
        this.message = message;
    }
    public String getMessage() {
        return message;
    }
}

@Configuration
@Import(MyImportSelector.class)
public class MainConfig {
    // 主配置类
}</code></pre>
]]></content:encoded>
					
					<wfw:commentRss>https://zhangxihai.cn/archives/342/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
