-
xml配置文件的形式VS配置类的形式
-
基于xml的形式定义bean的信息
//去容器中读取bean
public static void main( String[] args ) { ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml"); System.out.println(ctx.getBean("person")); } -
基于读取配置类的形式定义bean的信息
//去容器中读取Bean的信息(传入配置类)
public static void main(String[] args){
AnnotationConfigApplicationContext ctx=new AnnotationConfigApplicationContext(MainConfig.class);
System.out.println(ctx.getBean("person"));
}
//注意:通过@Bean的形式使用的话,bean的默认名称是方法名,若@Bean(Value="bean的名称"),那么bean的名称就是指定的
-
-
在配置类上写@ComponentScan注解来进行扫描
-
排除用法excludeFilters:排除@Controller注解的和TestService的
-
包含用法includeFilters:若使用包含的用法,需要把useDefaultFilters属性设置为false(true表示全部扫描)
-
配置bean的作用域对象
-
在不指定@Scope的情况下,所有的bean都是单例的bean,而且是饿汉加载(容器启动实例就创建好了)
-
指定@Scope为prototype表示为多实例的,而且还是懒汉模式加载(IOC容器启动的时候,并不会创建对象,而是在第一次使用时才创建)
@Bean @Scope(value="prototype") Public Person person(){ return new Person(); }
-
@Scope指定的作用域取值
-
Singleton单例模式(默认)
-
prototype多实例的
-
request同一次请求
-
session同一个会话级别
-
-
-
Bean的懒加载@Lazy
@Bean //主要针对单实例的bean的容器启动的时候,不创建对象,在第一次使用时才会创建该对象 @Lazy public Person person(){ return new Person }
-
@Conditional进行条件判断等
//场景:有两个组件TestAspect和TestLog,其中TestLog组件是依赖于TestAspect的组件 //应用:自己创建一个TestCondition的类实现Condition接口 public class TestCondition implements Condition{ @Override public Boolean matches(ConditionContext context,AnnotatedTypeMetadata medata){ // 判读容器中是否有TestAspect的组件 if(context.getBeanFactory().containsBean("TestAspect")){ return ture; } return false; } }
public class MainConfig{
-
往IOC容器中添加组件的方式
-
通过@CompentScan+@Controller@Service@Respository@Conpent
-
通过@Bean的方式来导入组件:适用于导入第三方组件的类
-
通过@Import来导入组件,导入 组件的id为类的全类名路径
-
通过@Import的ImportSelector类实现组件 的导入
//导入组件的id为类的全路径
public class TestImportSelector implements ImportSelector{
//可以获取导入类的注解信息
-
通过Import的ImportBeanDefinitionRegister导入组件
//可以指定Bean的名称
public class TestBeanDenifitionRegister implements ImportBeanDefinitionRegister{
-
-
通过实现FactoryBean接口来实现注册组件
public class CarFactoryBean implements FactoryBean<Car>{
//返回Bean对象
-
-
Bean的初始化方法和销毁方法
-
什么是bean的生命周期
bean的创建----->初始化----->销毁方法
//有容器管理bean的生命周期,我们可以自己指定bean的初始化方法和销毁方法 @Configuration public class MainConfig{ //指定bean 生命周期的初始化方法和销毁方法 @Bean(initMethod="init",destoryMethod="destory") public Car car{ reutrn new Car(); } } //针对于单实例bean的话,容器启动的时候,bean的对象就创建了,而且容器销毁的时候,也会调用bean的销毁方法 //针对多实例的bean的话,容器再启动的时候,Bean是不会被创建的,而且bean的销毁不受IOC容器的管理
-
通过InitalizingBean和DisposableBean的两个接口实现
-
通过Spring的BeanPostProcessor的bean的后置处理器会拦截所有bean的创建过程
public class TestBeanPostProcessor implements BeanPostPrecessor{
//在init方法调用之前
//BeanPostProcessor的执行时间
populateBean(beanName,mbd,instanceWrapper);
initializeBeanBean{
applyBeanPostProcessorBeforeInitialization();
invokeInitMethods{
isInitMethod{
isInitializingBean.afterPropertiesSet
自定义的init方法
}
applyBeanPostProcessorsAfterInitialization()方法
}
} -
通过@Value+@PropertySource来给组件赋值
public class Person{
//通过普通的方式
-
-
自动装配
-
@Autowired的使用
-
自动注入
@Repository public class TestDao{} @Service public class TestService{ @Autowired private TestDao testDao; }
-
自动注入结论
-
自动装配首先是按照类型进行装配,若在IOC容器中发现了多个相同类型的组件,那么就按照属性名称进行装配
@AutoWired private TestDao testDao; //比如上面代码:如果容器中有两个TestDao类型的组件,一个叫做testDao,一个叫做testDao2,那么我们通过@Autowired来修饰的属性名称是testDao,那么就加载容器的testDao组件,如果属性名称是testDao2,那么容器就加载的是testDao2组件
-
假设需要指定特定的组件来进行装配,我们可以通过使用@Qualifier("testDao")来指定装配的组件,或者在配置类上的@Bean加上@Primary注解
@Autowired @Qualifier("testDao") public TestDao testDao2;
-
假设容器中没有testDao也没有testDao2,那么在装配时就会抛出异常No qualifying bean of type'com.demo.testautowired.TestDao'available,若不想抛出异常,就需要指定required为false的时候就可以了
@Autowired(required=false) @Qualifier("testDao") private TestDao testDao2;
-
@Resource(JSR250规范):功能和Autowired差不多一样,但是不支持@Primary和@Qualifier的支持
-
@Inject(JSR330规范):需要导入JAR包依赖。功能支持@Primary,但是没有Required=false的功能
<dependency> <groupId>javax.inject</groupId> <artifactId>javax.inject</artifactId> <version>1</version> </dependency>
-
使用Autowired可以标注在方法上
-
标注在set方法上
-
标注在构造方法上
-
标注在配置类的入参中
-
-
-
我们自己的组件如何使用SpringIOC底层组件
//加入我们自己的组件组要使用ApplicationContext等,我们可以通过实现XXXAwire接口来实现
-
-
-