记录spring源码学习(基础及组件使用)第一天
查看下方地址学习,本页面只是自己学习代码的整理.
查看视频地址 https://www.bilibili.com/video/av59378064 侵删
创建项目引入的依赖
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.1.RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
1.@Bean
—原始加载bean的方法xml
--------------------实体类-------------------------------------
public class Person {
private String name;
private Integer age;
get AND set AND 有参无参构造方法..........
}
---------------------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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--古老方法生成bean并赋值-->
<bean id="person" class="com.gk.cap1.Person">
<property name="name" value="gaokang"></property>
<property name="age" value="21"></property>
</bean>
</beans>
---------------------Main方法-------------------------------------
public class MainTest1 {
public static void main(String[] args){
//把bean加载到容器中
ApplicationContext app = new ClassPathXmlApplicationContext("beans.xml");
//根据ID获取bean实例
Person person = (Person) app.getBean("person");
System.out.println(person);
}
}
—@Bean注解方式
---------------------@bean注解方法-------------------------------------
@Configuration//声明配置类
public class MainConfig {
@Bean
public Person personConfig(){
return new Person("gaokang-config",21);
}
}
---------------------Main方法-------------------------------------
public class MainTest2 {
public static void main(String[] args){
//把配置类加载到容器
AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(MainConfig.class);
//根据ID获取bean实例
Person person = (Person) app.getBean("personConfig");
System.out.println(person);
//查看beanID 如不制定bean的名字默认方法名 (@Bean("bean的名称"))
String[] nameForBean = app.getBeanNamesForType(Person.class);
for (String s : nameForBean) {
System.out.println(s);
}
}
}
2.@ComponentScan
– ComponentScan指定加载的注解bean的规则 三个参数如下
----value 指定加载的位置
----includeFilters 指定包含 使用时设置useDefaultFilters = false ,true时会默认加载全部(true时会把引用@component注解的全部加载进来)
----excludeFilters指定排除 使用时设置useDefaultFilters = true
---------------------添加几个注解类---------------------------------------
@Controller
public class OrderController {
}
@Repository
public class OrderDao {
}
@Service
public class OrderService {
}
---------------------配置类--------------------------------------
@Configuration
/*ComponentScan--指定规则
includeFilters指定加载的注解bean
includeFilters = {
@ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {Controller.class})
},useDefaultFilters = false
*/
/*指定排除的注解bean
excludeFilters = {
@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE,classes = {OrderController.class})
},useDefaultFilters = true
*/
/*
FilterType.ANNOTATION 指定注解 classes = {Controller.class}参数是指定的就是注解 Controller Service
FilterType.ASSIGNABLE_TYPE 指定类 classes = {Controller.class}参数是指定的就是类 OrderController
FilterType.CUSTOM 自定义类的规则 下方代码演示
*/
@ComponentScan(value = "com.gk.cap2" ,includeFilters = {
@ComponentScan.Filter(type = FilterType.CUSTOM,classes = {GKTypeFilter.class})
},useDefaultFilters = false)
public class Cap2MainConfig {
@Bean
public Person personConfig(){
return new Person("gaokang-config",21);
}
}
---------------------GKTypeFilter定义规则类---------------------------------------
public class GKTypeFilter implements TypeFilter {
/*
MetadataReader;读取到当前正在扫描类的信息
MetadataReaderFactory:可以获取到其他类的信息
*/
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
//获取当前类注解的信息
AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
//获取当前正在扫描类的信息
ClassMetadata classMetadata = metadataReader.getClassMetadata();
//获取当前类资源路径
Resource resource = metadataReader.getResource();
String className = classMetadata.getClassName();
System.out.println("------->"+className);
//如果返回true就是代表会加载当前这个bean所以当类名包含ervice时就会加载到容器中
if(className.contains("ervice")){
return true;
}
return false;
}
}
---------------------test类---------------------------------------
public class Cap2Test {
@Test
public void test01(){
AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(Cap2MainConfig.class);
for (String beanDefinitionName : app.getBeanDefinitionNames()) {
System.out.println(beanDefinitionName);
}
}
}
---------------------输出-----------------------------------------
------->com.gk.cap2.config.GKTypeFilter
------->com.gk.cap2.config.controller.OrderController
------->com.gk.cap2.config.dao.OrderDao
------->com.gk.cap2.config.service.OrderService
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
cap2MainConfig
orderService
personConfig
3.@Scope
– @Scope设置单||多实例,默认返回单实例
----@Scope设置单||多实例 prototype 设置多实例 singleton 单实例–默认
----单例时启动就会放到容器中—只会创建一次
----多实例调用时才会创建到容器中----调用几次创建几次
---------------------test类---------------------------------------
public class Cap3Test {
@Test
public void test01(){
AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(Cap3MainConfig.class);
for (String beanDefinitionName : app.getBeanDefinitionNames()) {
System.out.println(beanDefinitionName);
}
System.out.println(app.getBean("personConfig")==app.getBean("personConfig"));
}
}
---------------------配置类不加 @Scope------------------------------
@Configuration
public class Cap3MainConfig {
@Bean
public Person personConfig(){
System.out.println("创建bean");
return new Person("gaokang-config",21);
}
}
|------执行test类输出----|
创建bean
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
cap3MainConfig
personConfig
true
---------------------配置类加 @Scope------------------------------
@Configuration
public class Cap3MainConfig {
//容器默认返回单实例
//@Scope设置单||多实例 prototype 设置多实例
/*
@Scope设置单||多实例 prototype 设置多实例 singleton 单实例--默认
单例时启动就会放到容器中---只会创建一次
多实例调用时才会创建到容器中----调用几次创建几次
*/
@Scope("prototype")
@Bean
public Person personConfig(){
System.out.println("创建bean");
return new Person("gaokang-config",21);
}
}
|------执行test类输出----|
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
cap3MainConfig
personConfig
创建bean
创建bean
false
4.@Lazy
–@Lazy容器在启动时不会立马将bean加到容器中,只有在调用时才会将bean加入到容器.主要针对于单实例
---------------------test类---------------------------------------
public class Cap4Test {
@Test
public void test01(){
AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(Cap4MainConfig.class);
for (String beanDefinitionName : app.getBeanDefinitionNames()) {
System.out.println(beanDefinitionName);
}
System.out.println(app.getBean("personConfig"));
}
}
---------------------配置类不加 @Lazy------------------------------
@Configuration
public class Cap4MainConfig {
@Bean
public Person personConfig(){
System.out.println("bean加载了");
return new Person("gaokang-config",21);
}
}
|------执行test类输出----|
bean加载了
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
cap4MainConfig
personConfig
Person{name='gaokang-config', age=21}
---------------------配置类加 @Lazy------------------------------
@Configuration
public class Cap4MainConfig {
//@Lazy容器在启动时不会立马将bean加到容器中,只有在调用时才会将bean加入到容器.主要针对于单实例
@Lazy
@Bean
public Person personConfig(){
System.out.println("bean加载了");
return new Person("gaokang-config",21);
}
}
|------执行test类输出----|
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
cap4MainConfig
personConfig
bean加载了
Person{name='gaokang-config', age=21}