【spring源码】一、注解驱动开发

原来xml方式

img

https://www.jianshu.com/p/2692bf784976

BeanFactory 调用 initializeBean , initializeBean 调用所有的 BeanPostProcessor , BeanPostProcessor 调用 postProcessBeforeInitialization + postProcessAfterInitialization

注解驱动

Maven:spring-context

配置类

@Configuration

思路是用一个java类代替原来的xml文件

//配置类==配置文件
@Configuration  //告诉Spring这是一个配置类
//用ComponentScans可以指定多个扫描规则,也可以直接写ComponentScan
@ComponentScans(//相当于原来xml配置的包扫描//带s
    value = {
   
   
        @ComponentScan(value="com.atguigu",
                       includeFilters = {
   
   
                           /*	
                            @Filter(type=FilterType.ANNOTATION,classes={Controller.class}),
                            @Filter(type=FilterType.ASSIGNABLE_TYPE,classes={BookService.class}),*/
                           @Filter(type=FilterType.CUSTOM,classes={
   
   MyTypeFilter.class})//自定义扫描规则
                       },
                       useDefaultFilters = false
                      )	
    }
)
//@ComponentScan  value:指定要扫描的包
//excludeFilters = Filter[] :指定扫描的时候按照什么规则排除那些组件
//includeFilters = Filter[] :指定扫描的时候只需要包含哪些组件
//FilterType.ANNOTATION:按照注解
//FilterType.ASSIGNABLE_TYPE:按照给定的类型;
//FilterType.ASPECTJ:使用ASPECTJ表达式
//FilterType.REGEX:使用正则指定
//FilterType.CUSTOM:使用自定义规则
public class MainConfig {
   
   

    //给容器中注册一个Bean;也可以在配置类上@Import({.class})
    //类型为返回值的类型,id默认是用方法名作为id
    @Bean("person")//id//还有@Scope()//@Lazy//
    //@Conditional({})//@Conditional(LinuxCondition.class)这个类实现了Condition接口,具体可以去代码中看,实现了一个matches方法,返回bool//context.getEnvironment()获取操作环境,然后environment.getProperty("os.name")获取系统
    public Person person01(){
   
   
        return new Person("lisi", 20);
    }
}
public class MainTest {
   
   
    public static void main(String[] args) {
   
   
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfLifeCycle.class);
    }
@ComponentScan【bean注册方法1】

是扫描配置类外加了如下这些注解的类:@Component、@Service、@Repository、@Controller

加了这些注解后,对应的类就会注册一个bean实例,为了让配置类知道去找到你注解了类,需要在配置类上用@ComponentScans指明去哪里扫描。

//配置类==配置文件
@Configuration  //告诉Spring这是一个配置类

@ComponentScans(
    value = {
   
   
        @ComponentScan(value="com.atguigu",includeFilters = {
   
   
            /*						@Filter(type=FilterType.ANNOTATION,classes={Controller.class}),
						@Filter(type=FilterType.ASSIGNABLE_TYPE,classes={BookService.class}),*/
            @Filter(type=FilterType.CUSTOM,classes={
   
   MyTypeFilter.class})
        },useDefaultFilters = false)	
    }
)
//@ComponentScan  value:指定要扫描的包
//excludeFilters = Filter[] :指定扫描的时候按照什么规则排除那些组件
//includeFilters = Filter[] :指定扫描的时候只需要包含哪些组件
//FilterType.ANNOTATION:按照注解
//FilterType.ASSIGNABLE_TYPE:按照给定的类型;
//FilterType.ASPECTJ:使用ASPECTJ表达式
//FilterType.REGEX:使用正则指定
//FilterType.CUSTOM:使用自定义规则
public class MainConfig {
   
   
    //给容器中注册一个Bean;类型为返回值的类型,id默认是用方法名作为id
    @Bean("person")
    public Person person01(){
   
   
        return new Person("lisi", 20);
    }
}
@Bean【bean注册方法2】

在配置类中直接在一个自定义方法上注解@Bean,返回的对象就会注册到容器中。

略嫌麻烦,常用@Import

//默认是单实例的
/**
	 * @Scope:调整作用域
	 * prototype:多实例的:ioc容器启动并不会去调用方法创建对象放在容器中。
	 * 					每次获取的时候才会调用方法创建对象;
	 * singleton:单实例的(默认值):ioc容器启动会调用方法创建对象放到ioc容器中。
	 * 			以后每次获取就是直接从容器(map.get())中拿,
	 * request:同一次请求创建一个实例,需要在web环境
	 * session:同一个session创建一个实例,需要在web环境
	 * 
	 * 懒加载:
	 * 		单实例bean:默认在容器启动的时候创建对象;
	 * 		懒加载:容器启动不创建对象。第一次使用(获取)Bean创建对象,并初始化;
	 */
//	@Scope("prototype")
@Lazy
@Bean("person")//@Bean(initMethod="init",destroyMethod="detory")//对应的init方法也在Person类里
//还有其他方法看生命周期部分
public Person person(){
   
   
    System.out.println("给容器中添加Person....");
    return new Person("张三", 25);
}
@Conditional

在@Bean的同个方法上注解@Conditional({自定义.class}): 按照一定的条件进行判断,满足条件给容器中注册bean。

注解里可以传入一个自定义的class对象,

/**
	 * @Conditional({Condition}) : 按照一定的条件进行判断,满足条件给容器中注册bean
	 * 如果系统是windows,给容器中注册("bill")
	 * 如果是linux系统,给容器中注册("linus")
	 */
@Conditional(LinuxCondition.class)//linux环境下才注册这个bean//自定义的class,返回bool
@Bean("linus")
public Person person02(){
   
   
    return new Person("linus", 48);
}
//---------package com.atguigu.condition;-----------------------------------
//判断是否linux系统
public class LinuxCondition implements Condition {
   
   

	/**
	 * ConditionContext:判断条件能使用的上下文(环境)
	 * AnnotatedTypeMetadata:注释信息
	 */
	@Override
	public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
   
   
		// TODO是否linux系统
		//1、能获取到ioc使用的beanfactory
		ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
		//2、获取类加载器
		ClassLoader classLoader = context.getClassLoader();
		//3、获取当前环境信息
		Environment environment = context.getEnvironment();
		//4、获取到bean定义的注册类
		BeanDefinitionRegistry registry = context.getRegistry();
		
		String property = environment.getProperty("os.name");
		
		//可以判断容器中的bean定义情况,也可以给容器中注册bean
		boolean definition = registry.containsBeanDefinition("person");
		if(property.contains("linux")){
   
   
			return true;
		}
		
		return false;
	}
}
@Import【bean注册方法3】

@Import标注在config注册类上,在注册ac的时候就会自动把@Import(Dog.class)里标注的类实例化注册到容器中

  • @Import(要导入到容器中的组件.class);容器中就会自动注册这个组件,id默认是全类名
  • @Import(new ImportSelector(){@Override}:返回需要导入的组件的全类名数组;(事务源码中会用到)
  • @Import(new ImportBeanDefinitionRegistrar(,){@Override}:手动注册bean定义到容器中(aop源码中会使用)
在Configuration类上标注:;
@Import({
   
   Color.class,Red.class,
         MyImportSelector.class,//返回需要导入的组件的全类名数组;实现ImportSelector接口,函数式接口返回数组即可。可以返回一个空数组,但不要返回一个null
         MyImpor
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值