Spring ioc容器的添加、赋值、注入

一、使用配置文件时获得ioc容器

ClassPathXmlApplicationContext(“配置文件位置”)
new 一个返回一个ico容器
ApplicationContext applicationContext=new ClassPathXmlApplicationContext(“配置文件位置”);
applicationContext.getBean(“bean标签的id”);该方法返回的是bean标签内的实体Bean

二、spring配置类就相当于之前的配置文件

1,配置类的创建

配置类上填加@Configuration,告诉spring这是一个配置类
2、容器中注册一个Bean,类型为返回值类弄,id默认为方法名,bean标签内设置值后id为该值,通过该注解填加的实例默认都是单实例的
方法上填加@Bean注解
例:
@Bean(“person")
public Person person(){
return new Person(“lisi”,20);
}
3、注解式的获取ico容器

@SuppressWarnings("resource")
AnnotationConfigApplicationContext  applicationContext = new AnnotationConfigApplicationContext(配置类);
*           ConfigurableEnvironment  environment= applicationContext.getEnvironment();//获取当前的运行环境
environment.getProperty("os.name")//获得当前系统为windows 或linux

 applicationContext.getBean(实体bean.class);//通过类型获取容器内的实体Bean
applicationContext.getBeanNamesForType(实体bean.class)//返回一个String数组,ioc容器中的Bean那么数组

三、自动扫描组件&指定扫描规则

@ComponentScan(value=“扫描包路径”)
在配置类上填加该注解()指定注解扫描包路径
@ComponentScans()该注解参数为一个数组,包含多个@componentScan()
规则:
1,指定扫描的时候按照什么规则排除那些组件

@ComponentScan(value=“扫描包路径”,excludeFilters={
@Filter(type=FilterType.ANNOTATION,classes={controller.class,Service.class})
})
2、指定扫描的时候只需要包含哪些组件

@ComponentScan(value=“扫描包路径”,includeFilters={
@Filter(type=FilterType.ANNOTATION,classes={controller.class,Service.class},useDefaultFilters=false)
})
使用该规则时,需要禁用掉默认的加载规则;

四、组件注册-自定义TypeFilter过滤规则

1、FilterType.ANNOTATION 按照注解
参照上一条
2、FilterType.ASSIGNABLE_TYPE:按照给定的类型
参数参照上一条,表明该类型的组件排除或加载
3、FilterType.ASPECTJ:使用ASPECTJ表达式
基本不会使用
4、FilterType.REGEX:使用正则表达式批定规则
5、FilterType.CUSTOM:使用自定议规则
通过TypeFilter的实现类实现match方法的返回的布尔类型来指定规则
该方法有两个参数:
metadataReader:读取到的当前正在扫描的类的信息
metadataReaderFactory:可以获取到其他任何类信息
两个参数的方法:
metadataReader.getAnnotationMetadata();//获取当前类注解信息
metadataReader.getClassMetadata();//获取当前正在扫描的类的类信息
metadataReader.getResource();//获取当前类的资源(类的路径等)

五、组件注册-@Scope-设置组伯作用域

@Scope(“prototype”):多实例的
多实例的时候ioc容器启动并不会去调用方法创建对象放在容器中,每次获取的时候才会调用方法创建对像
@Scope(“singleton”):单实例的(默认值)
单实例的时候ioc容器启动会调用方法创建对像放到ioc容器中,以后每次获取的时候都是从容器中获取(类似map.get())
@Scope(“request”):同一次请求创建一个实例
@Scoope(“session”):同一个session创建一个实例

六、组件注册-@Lazy-bean懒加载

懒加载 @Lazy:
单实例bean:默认在容器启动的时候创建对像;
懒加载:容器启动不创建对象。第一次使用(获取)Bean时创建对像,并且初始 化

七、组件注册-@Conditional-按照条件注册

@Conditional({Condition数组}) 按照一定的条件进行判断,满足条件给容器注册Bean,可以作用在类上,也可以作用在方法上
参数为实现Condition的类数组;通过每个实现类实现Condition的matches方法的返回的布尔类型来进行判断;
该matches访求有两个参数:
ConditionContext:判断条件能使用的上下文(环境)
AnnotatedTypeMetadata:注释信息
两个参数的方法:
ConditionContext对像.getBeanFactory()//获取到ioc使用的bean工厂
ConditionContext对像.getClassLoader()//获取类加载器
ConditionContext对像.getEnvironment();//获取当前环境信息
environment.getProperty(“os.name”)//获取操作系统名称
ConditionContext对像.getRegistry();//获取到bean定义的注册类

八、组件注册-@import-给窗口中快速导入一个组件

1、包扫描+组件标注注解(@Controller/@Service/@Repository…)
局限性:只能是针对自己写的类
2、@Bean[导入的第三方包里面的组件]
3、@Import[快速的给容器中导入一个组件],
1)@Import(要导入到容器中的组件);容器中就会自动注册这个组件;id默认是全类名
作用在配置类上

@Import({Color.class,Red.class})

@Import(Color.class)
2)、ImportSelector:这是一个接口, 实现这个接口,返回需要导入的组件的全类名数组;不能返回null,可以返回一个空数组,否则会报空指针异常
3)、ImportBeanDefinitionRegistrar:手动注册bean到容器中
这是一个接口,创建一个类实现这个接口,放到Flter当中;实现该接口中的registerBeanDefinitioins方法;该方法中两个参数:
AnnotationMetadata:当前类的注解信息
BeanDefinitionRegistry:BeanDefinition注册类;
把所有需要添加到窗口中的bean;调用BeanDefinitionRegistry.registerBeanDefinition手工注册进来
BeanDefinitionRegistry.containsBeanDefinition(“全类名”)//返回布尔类型,判断是容器中是否包含该类,可以做出判断
//指定Bean定义信息;(Bean的类型等信息)
RootBeanDefinition beanDefinition =new RootBeanDefinition(实体Bean.class);
//注册一个Bean,指定bean名
registry.registerBeanDefinition(“bean名”,beanDefinition);
4、使用Spring提供的FactoryBean(工厂Bean)
1)创建一个类实现FactoryBean
2)实现他的方法
getObject//反回一个Color对像,这个对象会添加到容器中
getObjectType//返回Color.class
isSingleton//返回布尔类型;true:单实例,在容器保存一份,false:多实例,每次获取都会创建一个新的
3)、默认获取到的是工厂bean调用getObject创建的对象
4)、要获取工厂Bean本身,我们需要给id前面加一个&
&colorFactoryBean

九、生命周期-@Bean指定初始化的销毁方法

bean的生命周期:
bean创建—初始化—销毁的过程
容器管理bean的生命周期;
我们可以自定义初始化和销毁方法;容器在bean进行到当前星命周期的时候我们自定义初始化和销毁
初始化:
对象创建完成,并赋值好,调用初始化方法。。。。
销毁:
单实例:容器关闭的时候
多实例:容器不会管理这个bean;容器不会调用销毁方法
遍历得到容器中所有的BeanPostProcessor;挨个执行beforeInitialization,一但返回null,跳出for 循环,不会执行后面的BeanPostProcessor.postProcessorsBeaforeInitialization
BeanPostProcessor原理:
populateBean(beanName,mbd,instanceWrapper);//给bean进行属性赋值
initializeBean
{
//初始化之前
applyBeanPostProcessorsBeforeInitialization(wrappedBean,beanName)
invokeInitMethods(beanName,wrappedBean,mbd);执行自定义初始化
//初始化之后
applyBeanPostProcessorsAfterInitialization(wrappedBean,beanName)
}

1)、指定初始化和销毁方法;
通过@Bean指定init-method和destroy-method;
2)、通过让Bean实现InitializingBean(定义初始化逻辑),
DisposableBean(定义销毁逻辑)
3)、可以使用JSR250;
@PostConstruct:在bean创建完成并且属性赋值完成;来执行初始化方法
@PreDestroy:在bean从ioc容器中销毁之前,通知我们进行清理工作
4)、BeanPostProcessor【接口】,bean的后置处理器;在bean初始化前后进行一些处理工作;类上填加@Componet注解填加到ioc容器中,spring就可以让它工作;
PostProcessBeforeInitialization:在初始化之前工作
PostProcessAfterInitialization:在初始化之后工作
spring底层对BeanPostProcessor的使用:
bean赋值,注入其他组件,@Autowired,生命周期注解功能,@Async等等都是都是使用的BeanPostPro

cessor

十、属性赋值@Value

      在实体bean的属性上使用@Value()赋值
1、基本数值   @Value(12)
2、可以写SpEL:@Value("#{20-2}")
3、可以写${}:取出配置文件中的值:取出配置文件【properties】中的值(在运行环境变量里面的值)
 在配置类上使用@PropertySource读取外部配置文件中的k/v保存到运行的环境变量中,加载完外部的配置文件以后使用${}取出配置文件的值
AnnotationConfigApplicationContext applicationContext=new AnnotationConfigApplicationContext();
ConfigurableEnvironment environment=applicationContext.getEnvironment()
environment.getProperty("配置文件中的key值")也可以加载配置文件中的k对应的value
例:
@PropertySource(value={"classpath:/properties配置文件路径"})

十一、自动装配-@Autowired@Qualifier&@Primary

自动装配:
spring利用依赖注入(DI),完成对IOC容器中各个组件的依赖关系赋值
1、@Autowired:自动注入
	1)、默认优先按照类型去容器中找对应的组件:applicationContext.getBean(BookDao.class);
	2)、如果找到多个相同类型的组件,再将属性的名称作为组件的id去容器中查找 ;applicationContext.getBean("bookDao");
	BookService{
	@Autowired
	BookDao bookDao;
	}
	3)、@Qualifier("bookDao"):使用该注解指定需要装配的组件的id,而不是使用属性名
	4)、自动装配默认一定要将属性赋值好,没有就会报错;
	可以使用@Autowired(required=false);表明自动装配时,找到就装配,找不到就不装配,不会报错;
	5)、@Primary:让Spring 进行自动装配的时候,默认使用首先的bean
	 也可以同时使用@Qualifier指定需要装配的bean的名字,此注解优先权高于@Primary
2、Spring还支持使用@Resource(JSR250)和@Inject(JSR330)[java规范的注解】
	@Resource:
	1)、可以和@Autowired一样实现自动装配功能;默认是按照组件名称进行装配的;
	2)、@Resource(name="bookDao2")来指定要装配的组件名称
	不支持@Primary功能,不支持@Autowired(reqiured=false);
	@Inject:
	需要导入javax.inject的包,和Autowired的功能一样,只是没有reqiured这个属性
	@Autowired:Spring定义的;@Resource、@Inject都是java规范;
	AutowiredAnnotationBeanPostProcessor:解析完成自动装配功能;
3、@Autowired:构造器,参数,方法,属性;都可以使用该注解;都是从容器中获取参数组件的值
	1)、  标注在方法,Spring容器创建当前对象,就会调用方法,完成赋值,方法使用的参数、自定义类型的值从ioc容器中获取;@Bean标注的方法创建对象的时候,方法参数的值从容器中获取;默认不写@Autowired效果是一样的,都 能自动装配
	2)、标在构造器上;如果组件只有一个有参构造器,这个有参构造器的@Autowiredd可以省略,参数位置的组件还是可以自动从容器中获取
	默认加在ioc容器中的组件,容器启动会调用无参构造器创建对像,再进行初始化赋值等操作;构造器要用的组件,都是从容器中获取
	3)、放在参数位置:
4、自定义组件想要使用Spring容器底层的一些组件(ApplicationContext,BeanFactory......);自定义组件实现xxxAware;在创建对象的时候,会调用接口规定的方法注入相关组件;Aware;
	把Spring底层一些组件注入到自定义的Bean中;
	xxxAware:功能使用xxxProcessor;
	例:
	ApplicationContextAware==>ApplicationContextAwareProcessor;
4、profile:指定组件在哪个环境的情况下才能被注册到容器中,不指定,在任何环境下都能注册到容器中;
	Spring为我们提供的可以根据当前环境,动态的激活和切换一系列组件的功能;
	开发环境、测试环境、生产环境;
	*              切换环境:
    1、使用命令行动态参数:在虚拟机参数位置加载-Dspring.profiles.active=开发环境标识
     2、使用代码切换:
	    1)、创建一个applicationContext,ioc容器
		AnnotationConfigApplicationContext applicationContext=new AnnotationConfigApplicationContext();
	    2)、设置需要激活的环境
		applicationContext.gtEnvironment().setActiveProfiles("环境标识")//可以是多个,用逗号分隔
	    3)、注册主配置类
		applicationContext.register(配置类.class);
	    4)、启动刷新容器
		applicationContext.refresh();
例如在不同环境使用不同的数据源
数据源:(/a)(/b)(/c)
*配置类下设置数据源:
ComboPooledDataSource dataSource=new ComboPooledDataSource();
dataSource.setUser("root");
dataSource.setPassword("密码");
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/test");
dataSource.setDriverClass("com.mysql.jdbc.Driver");
1)、加了环境标识的bean,只有这个环境被激活的时候才能注册到容器;
默认是default环境
2)、写在配置类上,只有是指定环境的时候,整个配置类里面的所有配置才能开始生效
3)、没有标注环境标识的bean在任何环境下都是加载的
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值