我们学习spring 的第一天就知道 spring 主要的两大特性就是 IOC 、AOP
基于平时的开发工作我们也主要是写一写业务代码,很难接触到借助于spring 封装一些中间件,这也导致我们对spring的理解不够深入,spring可谓是对软件设计的原则和设计模式应该的出神入化了,面向对象的思想再它的整个架构中都可以看到。今天我就 IOC 这点这个谈一下自己的理解
IOC The Inversion of Control (IoC) 控制反转,官方的解析就是 对象的创建和依赖管理由开发人员交给spring这个就字面意思理解确实是很容易懂。但是一句话就能把IOC 说清楚了吗?思与深而行与浅
我觉的这才是IOC 的亮点。
我对IOC的理解,IOC 确实是控制反转的思想,但是spring是怎样去实现的呢。目前我觉的有这几种
xml应该算最老的方式向spring中注入bean 了
spring.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean class="com.sunjin.vip.bean.User">
<property name="id" value="1"/>
<property name="name" value="sunjin"/>
bean>
beans>
public static void main(String[] args) {
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-application.xml");
User user = applicationContext.getBean(User.class);
System.out.println(user);
}
当前解析配置文件的过程
AbstractApplicationContext#refresh()
->obtainFreshBeanFactory() 这个方法去解析配置
@ComponentScan("com.sunjin.vip.controller")
public class CommonConfiguration {
}
@Controller
public class SayHelloController {
}
public static void main(String[] args) {
AnnotationConfigApplicationContext annotationConfigApplicationContext =
new AnnotationConfigApplicationContext(CommonConfiguration.class);
SayHelloController sayHelloController = annotationConfigApplicationContext.getBean(SayHelloController.class);
System.out.println(sayHelloController);
}
这这种方式也可以向spring容器注册bean 当然@ComponentScan生效的机制就是在ConfigurationClassPostProcessor中
public class ConfigurationRegisterBean {
@Bean("user1")
public User user(){
User user = new User();
user.setId("1");
user.setName("sunjin");
return user;
}
@Bean("user2")
public User user2(){
User user = new User();
user.setId("2");
user.setName("sj");
return user;
}
}
public static void main(String[] args) {
AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(ConfigurationRegisterBean.class);
User user = (User) annotationConfigApplicationContext.getBean("user2");
System.out.println(user.getName());
}
这种实现的方式是ConfigurationClassBeanDefinitionReader#loadBeanDefinitions(configClasses)
->loadBeanDefinitionsForBeanMethod(beanMethod)
这种方式去加载的bean
@Configuration
public class CommonConfiguration {
}
@ComponentScan(basePackageClasses = CommonConfiguration.class)
public class ConfigurationRegisterBean {
}
public static void main(String[] args) {
AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(ConfigurationRegisterBean.class);
CommonConfiguration commonConfiguration = annotationConfigApplicationContext.getBean(CommonConfiguration.class);
System.out.println(commonConfiguration);
}
//@Import 和 ImportSelector
@Import(ImportSelectorUser.class)
public class ImportSelectorUserConfig {
}
public class ImportSelectorUser implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
return new String[]{User.class.getName()};
}
}
//@Import 和 ImportBeanDefinitionRegistrar
@Import(ImportBeanDefinitionRegisterParcel.class)
public class ImportBeanDefinitionRegisterParcelConfig {
}
public class ImportBeanDefinitionRegisterParcel implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
RootBeanDefinition beanDefinition = new RootBeanDefinition();
beanDefinition.setBeanClass(Parcel.class);
registry.registerBeanDefinition("parcel", beanDefinition);
}
}
public class FactoryBeanParcel implements FactoryBean<Parcel> {
@Override
public Parcel getObject() throws Exception {
return new Parcel();
}
@Override
public Class<?> getObjectType() {
return Parcel.class;
}
@Override
public boolean isSingleton() {
return false;
}
}
@Configuration//无实际意义
public class FactoryBeanParcelConfig{
@Bean
public FactoryBeanParcel factoryBeanParcel(){
return new FactoryBeanParcel();
}
}
public static void main(String[] args) throws Exception {
AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(FactoryBeanParcelConfig.class);
FactoryBeanParcel bean = annotationConfigApplicationContext.getBean(FactoryBeanParcel.class);
System.out.println(bean.getObject());
}
这种方式的实现 利用了factoryBean的特性了,spring中的bean分两种一种普通的bean 一种是 factorybean 为了复杂对象的创建 spring 提供了factorybean
这种方式的注册bean我这就不在举例了 可以参考 @Profile
spring 的这个注解实现就是按照 Conditional
通过上面几种方式的说明不知道你对spring IOC的实现方式有没有自己的想法目前这期没有涉及到DI\DL 的部分下期开始会说明spring 中DI\DL的实现方式。
结束语
:spring 应该是目前使用最广的 java框架了 spring 的生态和它的编程思想赢响了一代又一代程序猿。