Spring Boot 希望 @Component 类成为 @Configuration 类中的 @Bean
Posted
技术标签:
【中文标题】Spring Boot 希望 @Component 类成为 @Configuration 类中的 @Bean【英文标题】:Spring Boot wants @Component class to be a @Bean in @Configuration class 【发布时间】:2019-10-08 06:32:15 【问题描述】:当我测试我的@Component
类时,Spring boot 告诉我这个类应该在@Configuration
类中声明为@Bean
:
Field c in org.accountingSpringBoot.AccountingSpringBootApplication required a bean of type 'org.util.Cryptography' that could not be found.
The injection point has the following annotations:
- @org.springframework.beans.factory.annotation.Autowired(required=true)
Action:
Consider defining a bean of type 'org.util.Cryptography' in your configuration.
代码:
主类:
@SpringBootApplication
public class AccountingSpringBootApplication implements CommandLineRunner
@Autowired
ApplicationContext ctx;
@Autowired
Cryptography c;
public static void main(String[] args)
SpringApplicationBuilder builder = new SpringApplicationBuilder(AccountingSpringBootApplication.class);
builder.headless(false);
ConfigurableApplicationContext context = builder.run(args);
// SpringApplication.run(AccountingSpringBootApplication.class, args);
@Override
public void run(String... args) throws Exception
System.out.println(c.decrypt(c.encrypt("password")));
配置类:
@Configuration
@PropertySource("classpath:application.properties")
public class AppConfig
@Autowired
private Environment env;
@Bean
@Scope(scopeName = "singleton")
public SessionHandler sessionHandler()
return new SessionHandler();
@Bean
@Scope(scopeName = "singleton")
public SessionFactory sessionFactory()
SessionFactory sessionFactory;
try
sessionFactory = new org.hibernate.cfg.Configuration().configure().buildSessionFactory();
catch (Throwable ex)
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
return sessionFactory;
@Bean
public SecretKey secretKey()
String secretKey = env.getProperty("crypto.secretkey");
byte[] decodedKey = Base64.getDecoder().decode(secretKey);
SecretKey originalKey = new SecretKeySpec(decodedKey, 0, decodedKey.length,
env.getProperty("crypto.algorithm"));
return originalKey;
@Component
类:
@Component
public class Cryptography
@Autowired
private SecretKey secretKey;
private Cipher cipher; // = Cipher.getInstance("AES");
public Cryptography()
try
System.out.println("hhhhh");
this.cipher = Cipher.getInstance("AES");
catch (NoSuchAlgorithmException | NoSuchPaddingException e)
// TODO Auto-generated catch block
e.printStackTrace();
public String encrypt(String plainText) throws Exception
byte[] plainTextByte = plainText.getBytes();
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
byte[] encryptedByte = cipher.doFinal(plainTextByte);
Base64.Encoder encoder = Base64.getEncoder();
String encryptedText = encoder.encodeToString(encryptedByte);
return encryptedText;
public String decrypt(String encryptedText) throws Exception
Base64.Decoder decoder = Base64.getDecoder();
byte[] encryptedTextByte = decoder.decode(encryptedText);
cipher.init(Cipher.DECRYPT_MODE, secretKey);
byte[] decryptedByte = cipher.doFinal(encryptedTextByte);
String decryptedText = new String(decryptedByte);
return decryptedText;
【问题讨论】:
我看不到你的测试,但你的测试中有@SpringBootTest
吗?这样你就可以使用 SpringBootContextLoader
来创建你的 bean。
@GabLeg 通过测试我的意思是在run(String... args)
中调用decrypt()
和encrypt()
哦,我明白了,我的错!只是为了确定,你的包名是 org.util
吗?如果没有,您可能正在使用org.util.Cryptography
的外部库。确保导入您的 Cryptography
类。
是的,我的包名是org.util
——这个类是我自己实现的
【参考方案1】:
您没有使用默认应用布局,因此您的 org.util.Cryptography
类未被发现。
有几种可能的解决方案
使用@ComponentScan
使用默认包布局。检查Locating the Main Application Class
从 Cryptography 类中删除 @Component(无论如何都没有发现它)。在返回 Cryptography 实例的配置类中声明一个使用 @Bean 注释的方法。 (您的配置类使用这种方法和一些 bean)
【讨论】:
【参考方案2】:您没有在代码中显示包声明,但错误显示AccountingSpringBootApplication
在包org.accountingSpringBoot
中,而Cryptography
在包org.util
中。
@SpringBootApplication
启用对带有注解的类的包和子包的组件扫描,即包org.accountingSpringBoot
。
由于Cryptography
在包org.util
中,所以不会被扫描,所以Spring容器看不到@Component
。
你可以:
将Cryptography
移动到org.accountingSpringBoot
的子包中,例如org.accountingSpringBoot.util
将AccountingSpringBootApplication
移动到包装org
(不推荐)
明确指定要扫描的包:
@SpringBootApplication(scanBasePackages="org.accountingSpringBoot", "org.util")
重新安排你的包结构。我推荐这个,因为你当前的包太通用了,例如:
org.janlan.accounting.AccountingApplication
org.janlan.accounting.util.Cryptography
janlan
可以是您的公司名称、您的姓名或类似名称。
您应该阅读有关 Spring Boot 应用程序的推荐包结构的文档:Locating the Main Application Class
【讨论】:
以上是关于Spring Boot 希望 @Component 类成为 @Configuration 类中的 @Bean的主要内容,如果未能解决你的问题,请参考以下文章
spring boot: 一般注入说明 @Component, application event事件为Bean与Bean之间通信提供了支持
Spring boot之SpringApplicationBuilder,@@Configuration注解,@Component注解
Spring Boot 之注解@Component @ConfigurationProperties(prefix = "sms")