🌴Caused by: java.lang.IllegalArgumentException: PropertySource named ‘configurationProperties’ does not exist、MutablePropertySources源码解析
🍉一、遭遇配置找不到
Caused by: java.lang.IllegalArgumentException: PropertySource named ‘configurationProperties’ does not exist
泻水置平地,各自东西南北流。
人生亦有命,安能行叹复坐愁?
酌酒以自宽,举杯断绝歌路难。
心非木石岂无感,吞声踯躅不敢言。-------鲍照《拟行路难·其四》
一首小诗开场,愁呀愁。好端端的 Springboot 项目说罢工就罢工,启动不了,直接开摆。
上日志:
Skip ProjectInfoInitializer.
2024-03-28 19:30:29.023 INFO 73744 --- [ main] c.t.zj.dossier.DossierApplication : Starting DossierApplication on xiezhongcaideMacBook-Pro.local with PID 73744 (started by xiezhongcai in /Users/xiezhongcai/code/thunisoft/浙江一张网/dossier-application)
2024-03-28 19:30:29.024 INFO 73744 --- [ main] c.t.zj.dossier.DossierApplication : The following profiles are active: ext
2024-03-28 19:30:29.048 INFO 73744 --- [ main] .e.DevToolsPropertyDefaultsPostProcessor : For additional web related logging consider setting the 'logging.level.web' property to 'DEBUG'
2024-03-28 19:30:30.003 INFO 73744 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode!
2024-03-28 19:30:30.005 INFO 73744 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data repositories in DEFAULT mode.
2024-03-28 19:30:30.022 INFO 73744 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 9ms. Found 0 repository interfaces.
2024-03-28 19:30:30.232 INFO 73744 --- [ main] e.p.ArteryEncryptPropertiesPostProcessor : 开始处理PropertySource
2024-03-28 19:30:41.189 INFO 73744 --- [ main] ptablePropertiesBeanFactoryPostProcessor : Post-processing PropertySource instances
2024-03-28 19:30:41.232 INFO 73744 --- [ main] c.u.j.EncryptablePropertySourceConverter : Converting PropertySource configurationProperties [org.springframework.boot.context.properties.source.ConfigurationPropertySourcesPropertySource$$EnhancerBySpringCGLIB$$28713cba] to EncryptablePropertySourceWrapper
2024-03-28 19:30:41.232 INFO 73744 --- [ main] c.u.j.EncryptablePropertySourceConverter : Converting PropertySource servletConfigInitParams [org.springframework.core.env.PropertySource$StubPropertySource$$EnhancerBySpringCGLIB$$6454f49a] to EncryptablePropertySourceWrapper
2024-03-28 19:30:41.232 INFO 73744 --- [ main] c.u.j.EncryptablePropertySourceConverter : Converting PropertySource servletContextInitParams [org.springframework.core.env.PropertySource$StubPropertySource$$EnhancerBySpringCGLIB$$6454f49a] to EncryptablePropertySourceWrapper
2024-03-28 19:30:41.233 INFO 73744 --- [ main] c.u.j.EncryptablePropertySourceConverter : Converting PropertySource systemProperties [org.springframework.core.env.PropertiesPropertySource$$EnhancerBySpringCGLIB$$a9823f25] to EncryptableMapPropertySourceWrapper
2024-03-28 19:30:41.233 INFO 73744 --- [ main] c.u.j.EncryptablePropertySourceConverter : Converting PropertySource systemEnvironment [org.springframework.boot.env.SystemEnvironmentPropertySourceEnvironmentPostProcessor$OriginAwareSystemEnvironmentPropertySource$$EnhancerBySpringCGLIB$$2cfae3c4] to EncryptableSystemEnvironmentPropertySourceWrapper
2024-03-28 19:30:41.233 INFO 73744 --- [ main] c.u.j.EncryptablePropertySourceConverter : Converting PropertySource random [org.springframework.boot.env.RandomValuePropertySource$$EnhancerBySpringCGLIB$$941a0e61] to EncryptablePropertySourceWrapper
2024-03-28 19:30:41.233 INFO 73744 --- [ main] c.u.j.EncryptablePropertySourceConverter : Converting PropertySource applicationConfig: [classpath:/application-ext.yml] [com.thunisoft.artery.spring.property.encrypt.decorator.ArteryEncryptMapPropertySourceDecorator] to EncryptableMapPropertySourceWrapper
2024-03-28 19:30:41.233 INFO 73744 --- [ main] c.u.j.EncryptablePropertySourceConverter : Converting PropertySource applicationConfig: [classpath:/application.yml] [com.thunisoft.artery.spring.property.encrypt.decorator.ArteryEncryptMapPropertySourceDecorator] to EncryptableMapPropertySourceWrapper
2024-03-28 19:30:43.628 ERROR 73744 --- [ main] o.s.boot.SpringApplication : Application run failed
java.lang.IllegalArgumentException: PropertySource named 'configurationProperties' does not exist
at org.springframework.core.env.MutablePropertySources.assertPresentAndGetIndex(MutablePropertySources.java:206)
at org.springframework.core.env.MutablePropertySources.replace(MutablePropertySources.java:156)
at com.ulisesbocchio.jasyptspringboot.EncryptablePropertySourceConverter.lambda$convertPropertySources$2(EncryptablePropertySourceConverter.java:32)
at java.util.ArrayList.forEach(ArrayList.java:1259)
at com.ulisesbocchio.jasyptspringboot.EncryptablePropertySourceConverter.convertPropertySources(EncryptablePropertySourceConverter.java:32)
at com.ulisesbocchio.jasyptspringboot.configuration.EnableEncryptablePropertiesBeanFactoryPostProcessor.postProcessBeanFactory(EnableEncryptablePropertiesBeanFactoryPostProcessor.java:52)
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:286)
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:174)
at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:705)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:531)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:140)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:742)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:389)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:311)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1213)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1202)
at com.thunisoft.zj.dossier.DossierApplication.main(DossierApplication.java:38)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.taobao.pandora.boot.loader.LaunchRunner.run(LaunchRunner.java:38)
at java.lang.Thread.run(Thread.java:750)
Stopping available components
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.taobao.pandora.boot.loader.LaunchRunner.run(LaunchRunner.java:38)
at java.lang.Thread.run(Thread.java:750)
Caused by: java.lang.IllegalArgumentException: PropertySource named 'configurationProperties' does not exist
at org.springframework.core.env.MutablePropertySources.assertPresentAndGetIndex(MutablePropertySources.java:206)
at org.springframework.core.env.MutablePropertySources.replace(MutablePropertySources.java:156)
at com.ulisesbocchio.jasyptspringboot.EncryptablePropertySourceConverter.lambda$convertPropertySources$2(EncryptablePropertySourceConverter.java:32)
at java.util.ArrayList.forEach(ArrayList.java:1259)
at com.ulisesbocchio.jasyptspringboot.EncryptablePropertySourceConverter.convertPropertySources(EncryptablePropertySourceConverter.java:32)
at com.ulisesbocchio.jasyptspringboot.configuration.EnableEncryptablePropertiesBeanFactoryPostProcessor.postProcessBeanFactory(EnableEncryptablePropertiesBeanFactoryPostProcessor.java:52)
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:286)
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:174)
at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:705)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:531)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:140)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:742)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:389)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:311)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1213)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1202)
at com.thunisoft.zj.dossier.DossierApplication.main(DossierApplication.java:38)
... 6 more
Exception in thread "main" java.lang.RuntimeException: An exception occurred while running. null
at com.taobao.pandora.boot.loader.IsolatedThreadGroup.rethrowUncaughtException(IsolatedThreadGroup.java:28)
at com.taobao.pandora.boot.loader.ReLaunchMainLauncher.reLaunch(ReLaunchMainLauncher.java:108)
at com.taobao.pandora.boot.loader.ReLaunchMainLauncher.launch(ReLaunchMainLauncher.java:40)
at com.taobao.pandora.boot.PandoraBootstrap.run(PandoraBootstrap.java:48)
at com.thunisoft.zj.dossier.DossierApplication.main(DossierApplication.java:37)
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.taobao.pandora.boot.loader.LaunchRunner.run(LaunchRunner.java:38)
at java.lang.Thread.run(Thread.java:750)
Caused by: java.lang.IllegalArgumentException: PropertySource named 'configurationProperties' does not exist
at org.springframework.core.env.MutablePropertySources.assertPresentAndGetIndex(MutablePropertySources.java:206)
at org.springframework.core.env.MutablePropertySources.replace(MutablePropertySources.java:156)
at com.ulisesbocchio.jasyptspringboot.EncryptablePropertySourceConverter.lambda$convertPropertySources$2(EncryptablePropertySourceConverter.java:32)
at java.util.ArrayList.forEach(ArrayList.java:1259)
at com.ulisesbocchio.jasyptspringboot.EncryptablePropertySourceConverter.convertPropertySources(EncryptablePropertySourceConverter.java:32)
at com.ulisesbocchio.jasyptspringboot.configuration.EnableEncryptablePropertiesBeanFactoryPostProcessor.postProcessBeanFactory(EnableEncryptablePropertiesBeanFactoryPostProcessor.java:52)
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:286)
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:174)
at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:705)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:531)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:140)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:742)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:389)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:311)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1213)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1202)
at com.thunisoft.zj.dossier.DossierApplication.main(DossierApplication.java:38)
... 6 more
Disconnected from the target VM, address: '127.0.0.1:51029', transport: 'socket'
Process finished with exit code 1
这日志都打印出来了,这不有手就行吗。
java.lang.IllegalArgumentException: PropertySource named 'configurationProperties' does not exist
快快快,把这个配置文件给我,我不就能启动了吗?
很遗憾,这个配置文件不是我们自己的,是 Springboot 的,怎么回事呢?
🌵二、MutablePropertySources
org.springframework.core.env.MutablePropertySources
这个类报错了,从日志上这里是外层的报错,我来看看怎么个事
/**
* The default implementation of the {@link PropertySources} interface.
* Allows manipulation of contained property sources and provides a constructor
* for copying an existing {@code PropertySources} instance.
*
* <p>Where <em>precedence</em> is mentioned in methods such as {@link #addFirst}
* and {@link #addLast}, this is with regard to the order in which property sources
* will be searched when resolving a given property with a {@link PropertyResolver}.
*
* @author Chris Beams
* @author Juergen Hoeller
* @since 3.1
* @see PropertySourcesPropertyResolver
*/
public class MutablePropertySources implements PropertySources {
private final List<PropertySource<?>> propertySourceList = new CopyOnWriteArrayList<>();
这个 List 维护了所有的配置文件,都会放到这里来
/**
* Replace the property source with the given name with the given property source object.
* @param name the name of the property source to find and replace
* @param propertySource the replacement property source
* @throws IllegalArgumentException if no property source with the given name is present
* @see #contains
*/
public void replace(String name, PropertySource<?> propertySource) {
int index = assertPresentAndGetIndex(name);
this.propertySourceList.set(index, propertySource);
}
这方法是根据名称去 List 里面找同名的配置文件,然后替换放进去,等会报错的代码就是这一行int index = assertPresentAndGetIndex(name);
/**
* Assert that the named property source is present and return its index.
* @param name {@linkplain PropertySource#getName() name of the property source} to find
* @throws IllegalArgumentException if the named property source is not present
*/
private int assertPresentAndGetIndex(String name) {
int index = this.propertySourceList.indexOf(PropertySource.named(name));
if (index == -1) {
throw new IllegalArgumentException("PropertySource named '" + name + "' does not exist");
}
return index;
}
🥝三、断点调试
分析调试
项目启动之初,就看到加载了 8 个配置文件,并且 configurationProperties 是加载到 List 里面了。
此时经过了公司内部封装的一个配置文件加密类
获取到MutablePropertySources的 List,遍历它进行加密之后再放回 List
放进来的时候,注意看 name=null
,这里就坏事了,加密后放进来 name 为空了。后面要是再调用int index = this.propertySourceList.indexOf(PropertySource.named(name));
通过name 去获取它、替换它就会返回空报错了。
好巧不巧,同事又引入了一个依赖想对配置文件进行加密
<!--ENC加解密 -->
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId>
<version>2.1.2</version>
</dependency>
跟踪到这里,我心里已经有了答案,两次加密:一次是公司封装的,一次是引入的jasypt进行加密
但是这个锅不能甩给 jasypt,它加密后放进来name 也是有的
都是加密,为啥公司这个加密后,name 就没了呢?
ArteryEncryptPropertiesPostProcessor走的代理去生成的 PropertySource 对象
private <T> PropertySource<T> proxyPropertySource(PropertySource<T> propertySource, ArteryEncryptPropertyResolver resolver) {
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.setTargetClass(propertySource.getClass());
proxyFactory.setProxyTargetClass(true);
proxyFactory.addInterface(ArteryEncryptPropertySource.class);
proxyFactory.setTarget(propertySource);
proxyFactory.addAdvice(new ArteryEncryptPropertySourceMethodInterceptor(propertySource, resolver));
return (PropertySource)proxyFactory.getProxy();
}
jasypt的EncryptablePropertySourceConverter去判断了一下,是否要走代理去成
private static <T> PropertySource<T> convertPropertySource(InterceptionMode interceptionMode, EncryptablePropertyResolver propertyResolver, EncryptablePropertyFilter propertyFilter, PropertySource<T> propertySource) {
return interceptionMode == InterceptionMode.PROXY
? proxyPropertySource(propertySource, propertyResolver, propertyFilter) : instantiatePropertySource(propertySource, propertyResolver, propertyFilter);
}
这里interceptionMode是WRAPPER,并没有走代理,instantiatePropertySource(propertySource, propertyResolver, propertyFilter)
直接包装返回了,如果走代理也是一样的处理方法,name 也会为空
源码
最后附上两个加密的类
ArteryEncryptPropertiesPostProcessor.class
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package com.thunisoft.artery.spring.property.encrypt.processor;
import com.thunisoft.artery.spring.property.encrypt.ArteryEncryptPropertySource;
import com.thunisoft.artery.spring.property.encrypt.aop.ArteryEncryptPropertySourceMethodInterceptor;
import com.thunisoft.artery.spring.property.encrypt.decorator.ArteryEncryptEnumerablePropertySourceDecorator;
import com.thunisoft.artery.spring.property.encrypt.decorator.ArteryEncryptMapPropertySourceDecorator;
import com.thunisoft.artery.spring.property.encrypt.decorator.ArteryEncryptPropertySourceDecorator;
import com.thunisoft.artery.spring.property.encrypt.resolver.ArteryEncryptPropertyResolver;
import java.lang.reflect.Modifier;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.core.Ordered;
import org.springframework.core.env.CommandLinePropertySource;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.EnumerablePropertySource;
import org.springframework.core.env.MapPropertySource;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertySource;
public class ArteryEncryptPropertiesPostProcessor implements BeanFactoryPostProcessor, Ordered {
private static Logger logger = LoggerFactory.getLogger(ArteryEncryptPropertiesPostProcessor.class);
private ConfigurableEnvironment environment;
public ArteryEncryptPropertiesPostProcessor(ConfigurableEnvironment environment) {
this.environment = environment;
}
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
logger.info("开始处理PropertySource");
MutablePropertySources propSources = this.environment.getPropertySources();
((List)StreamSupport.stream(propSources.spliterator(), false).filter((ps) -> {
return !(ps instanceof ArteryEncryptPropertySource);
}).map((ps) -> {
return this.makeEncrypt(ps, beanFactory);
}).collect(Collectors.toList())).forEach((ps) -> {
propSources.replace(ps.getName(), ps);
});
}
private <T> PropertySource<T> makeEncrypt(PropertySource<T> propertySource, BeanFactory bf) {
ArteryEncryptPropertyResolver propertyResolver = (ArteryEncryptPropertyResolver)bf.getBean(ArteryEncryptPropertyResolver.class);
try {
if (!CommandLinePropertySource.class.isAssignableFrom(propertySource.getClass()) && !Modifier.isFinal(propertySource.getClass().getModifiers())) {
logger.debug("尝试代理propertySource:{}", propertySource.getName());
return this.proxyPropertySource(propertySource, propertyResolver);
} else {
logger.debug("尝试包装propertySource:{}", propertySource.getName());
return this.decoratorPropertySource(propertySource, propertyResolver);
}
} catch (Exception var5) {
logger.warn("生成代理出错, 忽略此类:{}", propertySource.getClass().getName(), var5);
return propertySource;
}
}
private <T> PropertySource<T> proxyPropertySource(PropertySource<T> propertySource, ArteryEncryptPropertyResolver resolver) {
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.setTargetClass(propertySource.getClass());
proxyFactory.setProxyTargetClass(true);
proxyFactory.addInterface(ArteryEncryptPropertySource.class);
proxyFactory.setTarget(propertySource);
proxyFactory.addAdvice(new ArteryEncryptPropertySourceMethodInterceptor(propertySource, resolver));
return (PropertySource)proxyFactory.getProxy();
}
private <T> PropertySource<T> decoratorPropertySource(PropertySource<T> propertySource, ArteryEncryptPropertyResolver resolver) {
if (propertySource instanceof MapPropertySource) {
return new ArteryEncryptMapPropertySourceDecorator((MapPropertySource)propertySource, resolver);
} else {
return (PropertySource)(propertySource instanceof EnumerablePropertySource ? new ArteryEncryptEnumerablePropertySourceDecorator((EnumerablePropertySource)propertySource, resolver) : new ArteryEncryptPropertySourceDecorator(propertySource, resolver));
}
}
public int getOrder() {
return Integer.MAX_VALUE;
}
}
EncryptablePropertySourceConverter.java
package com.ulisesbocchio.jasyptspringboot;
import com.ulisesbocchio.jasyptspringboot.aop.EncryptableMutablePropertySourcesInterceptor;
import com.ulisesbocchio.jasyptspringboot.aop.EncryptablePropertySourceMethodInterceptor;
import com.ulisesbocchio.jasyptspringboot.wrapper.EncryptableEnumerablePropertySourceWrapper;
import com.ulisesbocchio.jasyptspringboot.wrapper.EncryptableMapPropertySourceWrapper;
import com.ulisesbocchio.jasyptspringboot.wrapper.EncryptablePropertySourceWrapper;
import com.ulisesbocchio.jasyptspringboot.wrapper.EncryptableSystemEnvironmentPropertySourceWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.aop.support.AopUtils;
import org.springframework.core.env.*;
import java.lang.reflect.Modifier;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
import static java.util.stream.Collectors.toList;
/**
* @author Ulises Bocchio
*/
@Slf4j
public class EncryptablePropertySourceConverter {
public static void convertPropertySources(InterceptionMode interceptionMode, EncryptablePropertyResolver propertyResolver, EncryptablePropertyFilter propertyFilter, MutablePropertySources propSources) {
StreamSupport.stream(propSources.spliterator(), false)
.filter(ps -> !(ps instanceof EncryptablePropertySource))
.map(ps -> makeEncryptable(interceptionMode, propertyResolver, propertyFilter, ps))
.collect(toList())
.forEach(ps -> propSources.replace(ps.getName(), ps));
}
@SuppressWarnings("unchecked")
public static <T> PropertySource<T> makeEncryptable(InterceptionMode interceptionMode, EncryptablePropertyResolver propertyResolver, EncryptablePropertyFilter propertyFilter, PropertySource<T> propertySource) {
if (propertySource instanceof EncryptablePropertySource) {
return propertySource;
}
PropertySource<T> encryptablePropertySource = convertPropertySource(interceptionMode, propertyResolver, propertyFilter, propertySource);
log.info("Converting PropertySource {} [{}] to {}", propertySource.getName(), propertySource.getClass().getName(),
AopUtils.isAopProxy(encryptablePropertySource) ? "AOP Proxy" : encryptablePropertySource.getClass().getSimpleName());
return encryptablePropertySource;
}
private static <T> PropertySource<T> convertPropertySource(InterceptionMode interceptionMode, EncryptablePropertyResolver propertyResolver, EncryptablePropertyFilter propertyFilter, PropertySource<T> propertySource) {
return interceptionMode == InterceptionMode.PROXY
? proxyPropertySource(propertySource, propertyResolver, propertyFilter) : instantiatePropertySource(propertySource, propertyResolver, propertyFilter);
}
public static MutablePropertySources proxyPropertySources(InterceptionMode interceptionMode, EncryptablePropertyResolver propertyResolver, EncryptablePropertyFilter propertyFilter, MutablePropertySources propertySources) {
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.setTarget(MutablePropertySources.class);
proxyFactory.setProxyTargetClass(true);
proxyFactory.addInterface(PropertySources.class);
proxyFactory.setTarget(propertySources);
proxyFactory.addAdvice(new EncryptableMutablePropertySourcesInterceptor(interceptionMode, propertyResolver, propertyFilter));
return (MutablePropertySources) proxyFactory.getProxy();
}
@SuppressWarnings("unchecked")
public static <T> PropertySource<T> proxyPropertySource(PropertySource<T> propertySource, EncryptablePropertyResolver resolver, EncryptablePropertyFilter propertyFilter) {
//Silly Chris Beams for making CommandLinePropertySource getProperty and containsProperty methods final. Those methods
//can't be proxied with CGLib because of it. So fallback to wrapper for Command Line Arguments only.
if (CommandLinePropertySource.class.isAssignableFrom(propertySource.getClass())
// Other PropertySource classes like org.springframework.boot.env.OriginTrackedMapPropertySource
// are final classes as well
|| Modifier.isFinal(propertySource.getClass().getModifiers())) {
return instantiatePropertySource(propertySource, resolver, propertyFilter);
}
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.setTargetClass(propertySource.getClass());
proxyFactory.setProxyTargetClass(true);
proxyFactory.addInterface(EncryptablePropertySource.class);
proxyFactory.setTarget(propertySource);
proxyFactory.addAdvice(new EncryptablePropertySourceMethodInterceptor<>(propertySource, resolver, propertyFilter));
return (PropertySource<T>) proxyFactory.getProxy();
}
@SuppressWarnings("unchecked")
public static <T> PropertySource<T> instantiatePropertySource(PropertySource<T> propertySource, EncryptablePropertyResolver resolver, EncryptablePropertyFilter propertyFilter) {
PropertySource<T> encryptablePropertySource;
if (needsProxyAnyway(propertySource)) {
encryptablePropertySource = proxyPropertySource(propertySource, resolver, propertyFilter);
} else if (propertySource instanceof SystemEnvironmentPropertySource) {
encryptablePropertySource = (PropertySource<T>) new EncryptableSystemEnvironmentPropertySourceWrapper((SystemEnvironmentPropertySource) propertySource, resolver, propertyFilter);
} else if (propertySource instanceof MapPropertySource) {
encryptablePropertySource = (PropertySource<T>) new EncryptableMapPropertySourceWrapper((MapPropertySource) propertySource, resolver, propertyFilter);
} else if (propertySource instanceof EnumerablePropertySource) {
encryptablePropertySource = new EncryptableEnumerablePropertySourceWrapper<>((EnumerablePropertySource) propertySource, resolver, propertyFilter);
} else {
encryptablePropertySource = new EncryptablePropertySourceWrapper<>(propertySource, resolver, propertyFilter);
}
return encryptablePropertySource;
}
@SuppressWarnings("unchecked")
private static boolean needsProxyAnyway(PropertySource<?> ps) {
return needsProxyAnyway((Class<? extends PropertySource<?>>) ps.getClass());
}
private static boolean needsProxyAnyway(Class<? extends PropertySource<?>> psClass) {
return needsProxyAnyway(psClass.getName());
}
/**
* Some Spring Boot code actually casts property sources to this specific type so must be proxied.
*/
private static boolean needsProxyAnyway(String className) {
return Stream.of(
"org.springframework.boot.context.config.ConfigFileApplicationListener$ConfigurationPropertySources",
"org.springframework.boot.context.properties.source.ConfigurationPropertySourcesPropertySource"
).anyMatch(className::equals);
}
}
🍅四、解决方法
很遗憾,人生就是一个不断妥协的过程,代码也是。公司封装的加密无法取缔,那么只有寻找它山之石。
最终我把jasypt 删掉了,确实好使了。告诉同事后,他心怀愧疚,连夜换了一个依赖
<dependency>
<groupId>org.jasypt</groupId>
<artifactId>jasypt</artifactId>
<version>1.9.3</version>
</dependency>
看了下代码,这个加密方法,没有了对MutablePropertySources下List 进行操作,留个悬念,这两个依赖有什么区别呢?关注我,我将继续为大家解惑