Spring Boot 希望@Component class 成为@Configuration class 中的@Bean
Spring Boot wants @Component class to be a @Bean in @Configuration class
当我测试我的 @Component
class 时,Spring 引导告诉我这个 class 应该在 [=19= 中声明为 @Bean
] class:
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.
代码:
主要class:
@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")));
}
}
配置class:
@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
class:
@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;
}
}
您没有使用默认的应用程序布局,因此未发现您的 org.util.Cryptography
class。
有几种可能的解决方案
- 使用
@ComponentScan
- 使用默认包布局。检查 Locating the Main Application Class
- 从密码学中删除@Component class(无论如何都没有发现)。在您的配置之一中声明一个用 @Bean 注释的方法 classes 是 returns 密码学的一个实例。 (您的配置 class 将此方法与一些 bean 结合使用)
您没有在代码中显示包声明,但错误显示 AccountingSpringBootApplication
在包 org.accountingSpringBoot
中,而 Cryptography
在包 org.util
中.
@SpringBootApplication
启用包的组件扫描和 class 的 sub-packages 携带注释,即包 org.accountingSpringBoot
.
由于 Cryptography
在包 org.util
中,它没有被扫描,所以 Spring 容器看不到 @Component
。
您可以:
将 Cryptography
移动到 org.accountingSpringBoot
的 sub-package,例如org.accountingSpringBoot.util
将AccountingSpringBootApplication
移动到包org
(不推荐)
明确指定要扫描的包:
@SpringBootApplication(scanBasePackages={"org.accountingSpringBoot", "org.util"})
Re-arrange 你的包结构。
我推荐这个,因为你现在的包太通用了,例如:
org.janlan.accounting.AccountingApplication
org.janlan.accounting.util.Cryptography
其中 janlan
可以是您的公司名称、您的姓名或类似名称。
您应该阅读有关 Spring 引导应用程序的推荐包结构的文档:Locating the Main Application Class
当我测试我的 @Component
class 时,Spring 引导告诉我这个 class 应该在 [=19= 中声明为 @Bean
] class:
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.
代码:
主要class:
@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")));
}
}
配置class:
@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
class:
@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;
}
}
您没有使用默认的应用程序布局,因此未发现您的 org.util.Cryptography
class。
有几种可能的解决方案
- 使用
@ComponentScan
- 使用默认包布局。检查 Locating the Main Application Class
- 从密码学中删除@Component class(无论如何都没有发现)。在您的配置之一中声明一个用 @Bean 注释的方法 classes 是 returns 密码学的一个实例。 (您的配置 class 将此方法与一些 bean 结合使用)
您没有在代码中显示包声明,但错误显示 AccountingSpringBootApplication
在包 org.accountingSpringBoot
中,而 Cryptography
在包 org.util
中.
@SpringBootApplication
启用包的组件扫描和 class 的 sub-packages 携带注释,即包 org.accountingSpringBoot
.
由于 Cryptography
在包 org.util
中,它没有被扫描,所以 Spring 容器看不到 @Component
。
您可以:
将
Cryptography
移动到org.accountingSpringBoot
的 sub-package,例如org.accountingSpringBoot.util
将
AccountingSpringBootApplication
移动到包org
(不推荐)明确指定要扫描的包:
@SpringBootApplication(scanBasePackages={"org.accountingSpringBoot", "org.util"})
Re-arrange 你的包结构。
我推荐这个,因为你现在的包太通用了,例如:org.janlan.accounting.AccountingApplication org.janlan.accounting.util.Cryptography
其中
janlan
可以是您的公司名称、您的姓名或类似名称。
您应该阅读有关 Spring 引导应用程序的推荐包结构的文档:Locating the Main Application Class