Spring2
IOC容器实例化Bean的三种方式
1. 使用无参构造器,通过反射实例化
<bean id="userService", class="com.starry.spring.test.UserServiceImpl" />
2. 使用类的静态方法(静态方法)
<bean id="userService", class="com.starry.spring.test.UserServiceImpl", factory-method="getUserServiceStatic">
注意:getUserServiceStatic是UserServiceImpl的静态方法,返回实例对象
3. 使用类的实例方法
<bean id="userService", class="com.starry.spring.test.UserServiceImpl" />
<bean id="", factory-bean="userService", factory-method="getUserService" />
注意:getUserService方法是UserServiceImpl类的实例方法,该实例方法返回想要的示例。
IOC容器中Bean的作用域:Scope值标识
1. Singleton: 单例模式
容器中只会存在一个bean对象;其生命周期与容器共存亡;
2. Prototype:原型模式
每次getBean方法获取对象时都会创建一个新的对象,该实例对象无法通过容器进行销毁;
IOC容器Bean的属性
- id
- name
- class
- factory-bean
- factory-method
- init-method
- destory-method
- scope
- lazyInit
IOC容器中Bean的两种注入方式
- set方法注入,通过property标签注入(name,value,ref)
- 构造函数注入,通过construct-arg标签注入(name,value,ref)
IOC容器中Bean的实例化方式
1. 纯XML形式
使用xml配置IOC容器,通过Beans标签和bean标签配置类的基本信息,在启动容器的时候就会初始化配置的bean.
【J2EE通过ClassPathXmlApplicationContext类启动,并把xml文件地址作为参数;Web通过ClassLoaderListener监听配置类】
2. XML+注解形式【第三方jar包中的类实例化用xml形式,其他用注解】
注意依赖关系,使用set方式注入第三方依赖到自定义的bean中。
需要在xml中开启包的扫描,这样才能让注解的包实例化。
<context:component-scan base-package="" />
如果使用properties文件定义jdbc属性值,那么还需要引入外部文件
<context:property-placeholder localtion="classpath:jdbc.properties" />
3. 纯注解形式
主要是把xml中的内容通过注解形式来表示。
@Configuration. 注解修改一个类,表明次类是配置类,后续通过AnnotaionConfigurationApplication类启动的时候需要传递给类;
@Import(class) 注解修饰类,会把其他的配置类聚合到某一个配置类,方便在后续启动IOC容器的时候指定一个配置类即可
@ComponetScan 注解表示开启包的扫描
@PropertySource 注解表示引入外部文件
@Bean注解修饰返回第三方类实例的方法,使得该对象加入到IOC容器中;
@Value注解修饰属性,使得外部文件的值可以注入到该属性值中
实例化bean的注解
@Component @Controller @Service @Repository
以上是用在类上,帮助类进行实例化的。注解的含义相同,名称不同是用来区分实例化不同层的类。
@Autowired @Qualifier @Resource
以上是用来注入依赖的,前两个是spring提供 的,最后一个是java自带的;@Autowired是按照类型注入的,如果IOC容器中有相同类型的多个的bean实例,那么可以使用@Quailfer(“”)注解按照id来注入;@Resource是按照byName注入的,在jdk11被移除掉了,如果要使用需要单独引入javax-annotation的jar包。
注意:J2EE启动SpringIOC容器和Web启动IOC容器的区别。
SpringIOC的高级特性
1. 延迟加载
含义:针对singleton对象,默认在IOC容器启动的时候会初始化,如在bean里面配置lazy-init属性为true,那么只有在使用的时候才会初始化。所谓的使用,可以是被其他已经实例化的类依赖,也可以是通过getBean方法获取对象。
使用:xml形式是通过lazy-init属性设置,也可以在beans里面通过lazy-default设置全局属性;注解形式是通过在类上设置@Lazy注解即可,默认为true。
场景:对不常用的类设置为延迟加载。
2. BeanFactory和FactoryBean
含义:
- BeanFactory: 是IOC容器的顶层接口,定义了容器必备的属性,场景的子类有ApplicationContext;
- FactroyBean: 是一个接口,给我们提供自定义构造复杂Bean的入口;
使用:
- BeanFactory: 一般不会直接使用,它是IOC容器的顶层接口。
- FactoryBean: 一般用于实例化复杂Bean对象,才会实现该接口。
public class CompanyFactroy implements FactroyBean {
private String companyInfo; // 公司名,地址,规模
public void setCompanyInfo(String companyInfo){
this.companyInfo = companyInfo;
}
@Override
public Company getObject() throws Exception{
String[] strs = conpanyInfo.split(,);
Company company = new Company();
company.setName(strs[0]);
company.setAddress(strs[1]);
company.setScale(strs[2]);
return company;
}
@Override
public Class<?> getObjectType() {
return Company.class
}
@Override
public boolean isSingleton() {
return true;
}
}
xml注解实例化:
<bean id="companyBean" class="com.starry.test.spring.CompanyFactory">
<property name="companyInfo" value="starry,NJ,big" />
</bean>
注意:返回的实体bean是company对象,而非CompanyFactory;如果想要获得CompanyFactory,那么在需要通过“&companyBean”获得。
3. BeanFactoryPostProcessor & BeanPostProcessor
Spring提供两种后处理bean的扩展接口,分别为BeanFactoryPostProcessor和BeanPostProcessor;先初始化工厂,然后实例化对象,那么在初始化工厂之后,实例化对象之前,可以通过实现BeanFactoryPostProcessor处理一些事情,比如替换BeanDefinition中的占位符;在实例化对象之后(并不是Bean的整个生命周期完成),可以使用BeanPostProcessor后置处理一些事情。
含义:
- BeanFactoryPostProcessor:是一个接口,同时是一个扩展点,Bean工厂后置处理器;
public interface BeanFactoryPostProcessor {
void postProcessBeanFactory(ConfigurableListableBeanFactory var1) throws BeansException;
}
- BeanPostProcessor: 是一个接口,也是一个扩展点,Bean的后置处理器;接口提供了两个方法,before方法在init-method属性指定的方法之前执行,after方法则在init-method属性指定的方法之后执行;
public interface BeanPostProcessor {
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
使用:
- BeanPostProcessor
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postPorcessBeforeInitialization(Object bean, String beanName) throws BeansException{
System.out.println("实例化前的bean,处理bean");
return bean;
}
@Override
public Object postProcessAfterInitialization (Object bean, String beanName) throws BeanException {
System.out.println("实例化后的bean,处理bean");
return bean;
}
}
注意:这个后置处理器会针对所有的springBean进行处理,如果需要对特殊bean处理,那么需要通过beaName过滤。
- BeanFactoryPostProcessor 使用较少,可以参考PropertyPlaceholderConfigurer类。
附上springBean的生命周期图: