IOC容器就是具有依賴注入功能的容器,IOC容器負責實例化、定位、配置應用程序中的對象及建立這些對象間的依賴。應用程序無需直接在代碼中new相關的對象,應用程序由IOC容器進行組裝。
查看ioc容器中的組件
public static void main(String[] args) {
//1、返回IOC容器
ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);
//2、查看容器里面的組件
String[] names = run.getBeanDefinitionNames();
for (String name : names) {
System.out.println(name);
}
}
/**
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
springbootReviewApplication
org.springframework.boot.autoconfigure.internalCachingMetadataReaderFactory
org.springframework.boot.autoconfigure.AutoConfigurationPackages
org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration
...
...
**/
組件添加
Bean四種注入方式
- @ComponentScan包掃描+組件標注注解@Component(@Controller@Service@Repository)
- @Configuration+@Bean
使用場景:導入的第三方包里面的組件,將其他jar包中的類(類沒有Component等注解),加載到容器中。 - @Import快速給容器中導入一個組件
1)@Import(要導入到容器中的組件);容器中就會自動注冊這個組件,id默認是全類名
2)ImportSelector:返回需要導入的組件的全類名數組;
3)ImportBeanDefinitionRegistrar:手動注冊bean到容器中 - 使用Spring提供的 FactoryBean(工廠Bean)
1)默認獲取到的是工廠bean調用getObject創建的對象
2)要獲取工廠Bean本身,我們需要給id前面加一個&&xxxFactoryBean 注意類名是X,這里就是小寫的x?
@Configuration 和 @Bean
@Configuration(proxyBeanMethods = false) 告訴SpringBoot這是一個配置類、配置文件。@Configuration 用於定義配置類,可替換 xml
配置文件,被注解的類內部包含有一個或多個被 @Bean 注解的方法,這些方法將會被AnnotationConfigApplicationContext
或 AnnotationConfigWebApplicationContext
類進行掃描。
@Bean 是一個方法級別上的注解,主要用在 @Configuration 注解的類里,也可以用在 @Component 注解的類里。添加的bean的id為方法名。標注在方法上,返回某個實例的方法,這個實例就會交給Spring容器管理。
proxyBeanMethods
- FULL模式:
@Configuration(proxyBeanMethods = true)
,保證每個@Bean方法被調用多少次返回的組件都是單實例的。配置類組件之間有依賴關系,方法會被調用得到之前單實例組件,用 FULL 模式。 - LITE模式:
@Configuration(proxyBeanMethods = false)
,每個@Bean方法被調用多少次返回的組件都是新創建的,配置類組件之間無依賴關系用Lite模式加速容器啟動過程,減少判斷。 - Spring Boot 在2.2.0版本(依賴於Spring 5.2.0)起就把它的所有的自動配置類默認proxyBeanMethods = false,提高Spring啟動速度。
@Configuration(proxyBeanMethods = false)
public class ConfigDemo1 {
@Bean
public Student getStudent() {
Student student = new Student();
student.setAge(18);
student.setName("xiaoming");
return student;
}
}
@SpringBootApplication
public class SpringbootReviewApplication {
public static void main(String[] args) {
ConfigurableApplicationContext run = SpringApplication.run(SpringbootReviewApplication.class, args);
ConfigDemo1 configDemo1 = run.getBean(ConfigDemo1.class);
Student student1 = configDemo1.getStudent();
Student student2 = configDemo1.getStudent();
//返回false,如果proxyBeanMethods = true,則返回true
System.out.println(student1 == student2);
}
}
@Bean,@Component,@Service,@Repository 和 @Controller注解的區別
1.@Bean
標注在方法上,返回某個實例的方法,這個實例就會交給Spring容器管理。
2.@Component
作用於類上,相當於一個基類,跟 @Bean 一樣,可以托管到Spring容器進行管理。表示一個方法實例化、配置或者初始化一個Spring IoC容器管理的新對象
3.@Service, @Controller , @Repository
作用於類上,={@Component + 一些特定的功能}。這些注解在部分功能上是一樣的,但有一些不同:
@Controller注解類:SpringMVC的理念,進行前端請求的處理,轉發,重定向。包括調用Service層的方法。
@Service注解類:處理業務邏輯
@Repository注解類:作為DAO對象(數據訪問對象,Data Access Objects),這些類可以直接對數據庫進行操作。
@Controller、@Service、@Repository都屬於@Component
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Service {
@AliasFor(annotation = Component.class)
String value() default "";
}
使用bean
以上都是注冊bean,那怎么使用bean呢?
@Autowired 屬於Spring的注解 org.springframework.beans.factory.annotation.Autowired
@Resource 不屬於Spring的注解,JDK1.6支持的注解 javax.annotation.Resource
@Autowired
根據類的類型進行裝配
@Resource
根據類的名字進行裝配,也可以設定根據類的名字