IOC容器
我们常说的 “IOC容器 IOC容器”,其实就是org.springframework.context.ApplicationContext
,它负责实例化,配置和重装bean,通过读取配置元数据获取有关要实例化,配置和重装的对象的指令。配置元数据就是我们所写的配置文件或者Java注解等。
以下所示通过配置的xml文件作为配置元数据:
ApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"spring.xml", "spring1.xml"});
以下是通过配置类的方式实现的配置:
ApplicationContext context = new ClassPathXmlApplicationContext(myConfig.class);
刚刚说了,我们要用Spring的IOC容器来实例化Bean,实例化也就是初始化哈,那么如何实现初始化呢,Spring为我们提供了三种方式。
补充:classpath: 是什么
在以后的spring配置中会经常用到classpath:/xxx/xxx
来指定配置/资源文件的路径,现在提前就说一下什么是classpath:
。
在IDEA中的spring项目,项目目录结构一般是:
src:
main:
java:
resources:
test:
java:
pom.xml
但是这样的文件目录结构只是我们开发时的结构,当我们把项目打包运行的时候,文件的目录结构会发生变化,变成如下形式:
META-INF:
WEB-INF:
class:
lib:
....
其中lib目录存放的是maven引入的依赖,由此可见,之前项目结构下的java和resources下的文件,都被放在了class目录下。所以class这个文件夹,就是我们要找的classpath:
。另外:使用classpath:
这种前缀,就只能代表一个文件,使用classpath*:
这种前缀,则可以代表多个匹配的文件;在路径中使用双星号**
表示在任意目录下,也就是说在WEB-INF/classes/
下任意层的目录,只要符合后面的文件路径,都会被作为资源文件找到。classpath*:**/mapper/*Mapper.xml
三种初始化方式
@PostConstruct
这种方式是 Spring 非常提倡的一种方式,我们通常将其标记在方法上即可,通常习惯将这个方法起名为 init()
@PostConstruct
public void init() {
System.out.println("Inside init() method...");
}
InitializingBean
我们可以通过实现 InitializingBean
接口,在其唯一方法 afterPropertiesSet
内完成实例化的工作,但是 Spring Framework 官方并不建议我们通过这种方法来完成 Bean 的实例化,这是一种强耦合的方式,我们看到框架层面才会用到这个方法。
// Spring提供的InitializingBean 接口
public interface InitializingBean {
void afterPropertiesSet() throws Exception;
}
init-method
注解配置一般如下:
public class MyClass {
public void init() {
// perform post-creation logic here
}
}
@Configuration
public class myConfig {
// 此处指明初始化方法
@Bean(initMethod = "init")
public MyClass myclass() {
return new MyClass ();
}
}
或者,xml中配置如下:
<bean id="myClass" class="demo01.MyClass" init-method="init"/>
注意:三种方法同时存在时,三种方法的调用顺序依次是:@PostConstruct -> InitializingBean -> init-method.
另外 BeanPostProcessor
public interface BeanPostProcessor {
Object postProcessBeforeInitialization(Object var1, String var2) throws BeansException;
Object postProcessAfterInitialization(Object var1, String var2) throws BeansException;
}
这两个方法是在上述三种方式的前和后调用,是AOP切面编程思想,我们经常会使用 postProcessAfterInitialization
方法,通过读取 Bean 的注解完成一些后续逻辑编写与属性的设定。
三种销毁方式
@PreDestroy
这种方式是 Spring 非常提倡的一种方式,我们通常将其标记在方法上即可,通常习惯将这个方法起名为 destory()
@PreDestroy
public void destroy() {
System.out.println("destroy method");
}
}
DisposableBean
通过实现 DisposableBean
接口,在其唯一方法 destroy
内完成 bean 销毁的工作,但是 Spring Framework 官方并不建议我们通过这种方法来销毁 bean,这同样是一种强耦合的方式,我们看到框架层面才会用到这个方法。
public interface DisposableBean {
void destroy() throws Exception;
}
destroy-method
同样两种方式,一个是注解方式,一个是xml配置方式:
public class MyClass {
public void destory() {
// perform destroy logic here
}
}
@Configuration
public class myConfig {
@Bean(destroyMethod = "destroy")
public MyClass myclass() {
return new MyClass ();
}
}
或者:
<bean id="myClass" class="demo.MyClass" destory-method="destory"/>
注意:调用顺序:@PreDestroy -> DisposableBean -> destroy-method