目錄
1. 存儲 Bean 對象
1.1 配置掃描路徑
1.2 添加注解存儲 Bean 對象
1.2.1 @Controller(控制器存儲)
1.2.2?@Service(服務存儲)
1.2.3?@Repository(倉庫存儲)
1.2.4?@Component(組件存儲)
1.2.5?@Configuration(配置存儲)
1.3 使用多個類注解的原因
1.3.1 五大注解之間的關系
1.3.1 Bean 的命名規(guī)則
1.4 方法注解 @Bean
1.4.1 方法注解要配合類注解使用
1.4.2 重命名 Bean
1.4.3 給有參數的方法添加 Bean 注解?
1.4.4 Spring xml 配置的方式進行傳參
2. 根據日志定位問題
NoSuchBeanDefinitionException -- 沒有找到 Bean
在 Spring 中想要更簡單的存儲和讀取對象的核心是使用注解。
1. 存儲 Bean 對象
之前我們存儲 Bean 時,需要在 spring-config 中添加?行 bean 注冊內容才行,如下圖所示:
但是現(xiàn)在我們可以通過注解來代替上面的配置。
1.1 配置掃描路徑
想要將對象成功的存儲到 Spring 中,我們需要配置?下存儲對象的掃描包路徑,只有被配置的包下的所有類,添加了注解才能被正確的識別并保存到 Spring 中。
在 spring-config.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"
xmlns:content="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<content:component-scan base-package="com.bit.service"></content:component-scan>
</beans>
也就是說,即使添加了注解,如果不是在配置的掃描包下的類對象,也是不能被存儲到 Spring 中的。
1.2 添加注解存儲 Bean 對象
想要將對象存儲在 Spring 中,有兩種注解類型可以實現(xiàn):
1. 類注解:@Controller、@Service、@Repository、@Component、@Configuration。
2. 方法注解:@Bean。
1.2.1 @Controller(控制器存儲)
使用?@Controller 存儲對象:
@Controller
public class UseController {
public void sayHi(){
System.out.println("hi,Controller...");
}
}
接下來取對象:
public class App {
public static void main(String[] args) {
// 得到 Spring 上下文
ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
// 獲取 Bean 對象
UserController user = (UserController) context.getBean("userController");
// 使用 Bean
user.sayHi();
}
}
可以發(fā)現(xiàn)在使用 getBean() 方法時,我們直接使用了注解下類名的小駝峰的形式,可以看到運行無誤:
1.2.2?@Service(服務存儲)
使用?@Service 存儲對象:
@Service
public class UserService {
public void sayHi(){
System.out.println("Hi,Service...");
}
}
?接下來取對象:
public class App {
public static void main(String[] args) {
// 得到 Spring 上下文
ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
// 獲取 Bean 對象
UserService userService = (UserService)context.getBean("userService");
// 使用 Bean
userService.sayHi();
}
}
1.2.3?@Repository(倉庫存儲)
使用?@Repository 存儲對象:
@Repository
public class UserRepository {
public void sayHi(){
System.out.println("Hi,Repository...");
}
}
接下來取對象:
public class App {
public static void main(String[] args) {
// 得到 Spring 上下文
ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
// 獲取 Bean 對象
UserRepository userRepository = (UserRepository)context.getBean("userRepository");
// 使用 Bean
userRepository.sayHi();
}
}
1.2.4?@Component(組件存儲)
使用?@Component 存儲對象:
@Component
public class UserComponent {
public void sayHi(){
System.out.println("Hi,Component...");
}
}
?接下來取對象:
public class App {
public static void main(String[] args) {
// 得到 Spring 上下文
ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
// 獲取 Bean 對象
UserComponent userComponent = (UserComponent)context.getBean("userComponent");
// 使用 Bean
userComponent.sayHi();
}
}
1.2.5?@Configuration(配置存儲)
使用?@Configuration 存儲對象:?
@Configuration
public class UserConfiguartion {
public void sayHi(){
System.out.println("Hi,Configuration...");
}
}
?接下來取對象:
public class App {
public static void main(String[] args) {
// 得到 Spring 上下文
ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
// 獲取 Bean 對象
UserConfiguartion userConfiguartion = (UserConfiguartion)context.getBean("userConfiguartion");
// 使用 Bean
userConfiguartion.sayHi();
}
}
1.3 使用多個類注解的原因
通過不同的類注解更加明確當前類的用途:
- @Controller:表示的是業(yè)務邏輯層,控制器,通常是指程序的入口。比如參數校驗、參數類型轉換、前置處理工作等;
- @Servie:服務層,一般寫業(yè)務代碼、服務編排、調用 DB、調用第三方接口等;
- @Repository:持久層,倉庫,通常是指 DB 操作相關的代碼(Dao、mapper);
- @Component:其他的對象;
- @Configuration:配置層。
1.3.1 五大注解之間的關系
?查看 @Controller / @Service / @Repository / @Configuration 等注解的源碼發(fā)現(xiàn):
?這些注解里面都有?個注解 @Component,說明它們本身就是屬于 @Component 的“子類”。
1.3.1 Bean 的命名規(guī)則
通過以上舉例我們猜測:注解對應的 Bean 的名稱是首字母小寫。那么,真的如此嗎?此時就需要我們去查看一下官方的文檔。按住 CTRL + N 鍵進行搜索:
可以看到第四個是我們所需要的關于注解的,點進去后可以看到:
因此,我們得出結論:
當類名前兩位均為大寫時,需要返回自身類名;否則,返回首字母小寫后的類名。
1.4 方法注解 @Bean
1.4.1 方法注解要配合類注解使用
類注解是添加到某個類上的,而方法注解是放到某個方法上的,如以下代碼的實現(xiàn):
public class Users {
private String name;
private Integer age;
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
public void setAge(Integer age){
this.age = age;
}
@Configuration
public class BeanConfig {
@Bean
public Users user(){
Users user = new Users();
user.setName("小明");
user.setAge(18);
return user;
}
public Users user2(){
Users user = new Users();
user.setName("小藍");
user.setAge(19);
return user;
}
}
public class App {
public static void main(String[] args) {
// 得到 Spring 上下文
ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
// 獲取 Bean 對象
Users users = (Users) context.getBean("user");
// 使用 Bean
System.out.println(users.getName());
}
}
@Bean 無法直接單獨使用,必須搭配五大類注解使用。
Bean 對應生成的 Bean 名稱是方法名。
1.4.2 重命名 Bean
@Configuration
public class BeanConfig {
@Bean("aaa")
public Users user(){
Users user = new Users();
user.setName("小明");
user.setAge(18);
return user;
}
public Users user2(){
Users user = new Users();
user.setName("小藍");
user.setAge(19);
return user;
}
}
@Configuration
public class BeanConfig {
@Bean(name={"aaa","user"})
public Users user(){
Users user = new Users();
user.setName("小明");
user.setAge(18);
return user;
}
public Users user2(){
Users user = new Users();
user.setName("小藍");
user.setAge(19);
return user;
}
}
@Configuration
public class BeanConfig {
@Bean({"aaa","user"})
public Users user(){
Users user = new Users();
user.setName("小明");
user.setAge(18);
return user;
}
public Users user2(){
Users user = new Users();
user.setName("小藍");
user.setAge(19);
return user;
}
}
以上三種方法均可實現(xiàn) Bean 的重命名,重命名之后則無法使用原來的方法名來獲取 Bean:
?對五大類注解同樣可以使用以上重命名的方法。
1.4.3 給有參數的方法添加 Bean 注解?
@Configuration
public class BeanConfig {
@Bean({"aaa","user"})
public Users user(Integer age){
Users user = new Users();
user.setName("小明");
user.setAge(age);
return user;
}
public Users user2(){
Users user = new Users();
user.setName("小藍");
user.setAge(19);
return user;
}
}
直接運行上述代碼會報錯,因為并沒有找到 age 這個對象:
?此時修改代碼如下:
@Configuration
public class BeanConfig {
@Bean
public Integer age(){
return 15;
}
@Bean({"aaa","user"})
public Users user(Integer age){
Users user = new Users();
user.setName("小明");
user.setAge(age);
return user;
}
public Users user2(){
Users user = new Users();
user.setName("小藍");
user.setAge(19);
return user;
}
}
?將對象交給 Spring 管理后,會自動匹配對應的類型,還可以通過其他方式去讀?。ū热缗渲梦募校?strong>當只有一個 @Bean 注解時,根據類型進行匹配;當有多個 @Bean 時,根據名稱進行匹配。
1.4.4 Spring xml 配置的方式進行傳參
public class BeanConfig {
public Users user(String name){
Users user = new Users();
user.setName(name);
user.setAge(12);
return user;
}
}
<bean id="user" class="springcore">
<constructor-arg name="name" value="小明"></constructor-arg>
</bean>
當需要注入的是對象時,要寫引用:
public class UserController {
private UserService userService;
public UserController(UserService userService){
this.userService = userService;
}
public void sayHi(){
System.out.println("hi,Controller...");
}
}
<bean id="user" class="springcore">
<constructor-arg name="userService" ref="userService"></constructor-arg>
</bean>
2. 根據日志定位問題
NoSuchBeanDefinitionException -- 沒有找到 Bean
Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'userController' available
?沒有名為“userController”的bean可用。
可以看到此時是因為注解被注釋了,不再生效的原因。
出現(xiàn)以上日志時還有另一種可能原因,如下圖所示:
也就是說當我們的掃描路徑與實際不符時,同樣會出現(xiàn)找不到 Bean 的情況。
除了以上兩種情況當我們通過注解獲取 Bean 時,類名不符合要求同樣會生成以上的日志,具體如下圖所示:
還有一種情況是因為將注解重命名了,但是使用的依然時未重命名之前的注解,同樣會生成以上日志:
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'java.lang.Integer' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}?
沒有可用的“java.lang.Integer”類型的限定bean。文章來源:http://www.zghlxwxcb.cn/news/detail-610780.html
文章來源地址http://www.zghlxwxcb.cn/news/detail-610780.html
到了這里,關于3. Spring 更簡單的讀取和存儲對象(五大類注解 & 方法注解)的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!