大明王朝里面提到了三思这个词的解释,三思就是思危,思退,思变,也就是思考所处的危险,自己不对的地方,然后退到一个安全的地方,然后改变自己,从而争取到更好的机会,最重要的是一个思字,很多事情没有思考,那就是高屋建瓴,基础不牢,地动山摇,这也是为什么,编程要学习算法,要学习源码。
现在来说说,我们最熟悉的Spring Ioc
说是熟悉,但我总觉得,他是一个最熟悉的陌生人,为什么这么说呢,因为我们可能就是在调用他的API而已。
说他之前,先说说Spring的组成
1 核心Core 他主要是由BeanFactory来构成的
2 上下文Context 这个我们应该熟悉,加载配置文件之后,解析成的各种ApplicationContext就是他了。
3 Spring Dao 是一个抽象层,如果数据库方面报错抛异常主要由他管理
4 Spring Aop 这个应该都知道
5 Spring web 也不说了
这个是Spring的架构,具体就不讲了。
从里面看Spring是非常大的,包罗万象。
于是,他就有了一个缺点,是啥呢?
1 重量级框架
他太大了,什么都有,即便我用不到的也有,我之前写JPA的时候,他的设计是,有一个标识作用的接口Resiposity,然后有三个接口分别继承他,每一个继承上一个,这样最后一个的功能就最强大,那么问题来了,既然最后一个最强大,那我用最后一个不就可以了,那前面的还有什么存在的必要,表面上看是这样的,但是功能强大的也有其负面,就是加载的东西太多了,会消耗更多的内存,所以这反而是一个缺点
2 学习难度大
Spring的源码体系太过庞大,一个上下文就好多类,而且为了代码及其灵活,使用很多的设计模式导致代码的可读性发生下降,学习成本变得更高,当然,如果知识想调用Api接口那就没事了,但是,做技术的要有最技术的追求,还是要对其学习
3 配置复杂
现在很多项目还是使用xml的形式配置,就导致配置的成本变的比较高
回归正题,Spring Ioc到底是啥? 我想只要学过java的都会说,控制反转,依赖注入。
那啥是控制反转,啥又是依赖注入,他又是怎么实现的。
那很多人就会说,控制反转就是控制权交给Spring管理,而不是自己管理。再具体点呢,是什么控制权给了Spring,我想很多人就会答不上来了。
来看下代码
@Service
public class SpringDemo
{
@Autowired
private ScheduleJob scheduleJob;
public void test(){
scheduleJob.cronTask();
}
}
这段代码,如果没有通过Spring的@Autowired那会怎么样呢,那他就是会报错的,为什么呢,因为对象是null的,我们知道jvm是要对象实例话之后才会在堆中给对象分配内存空间,才能调用对象中的方法,因为是null所以,调用不了,当然就报错啦。
那用上了@Autowired为什么就不报错了呢,其实这个就是我们说的控制反转,加上了@AutoWired就是从Spring的BeanFactory 中取值,而BeanFactory 中存储了已经实例化好的对象,这个对象是Spring帮助我们实例化的。而Spring容器帮我们实例化而不是我们手动实例化,这个就是控制反转了,控制就体现在对象的实例化上,之前使我们自己写代码手动实例,现在我们可以歇菜了,Spring帮我们实例化,这样就很清晰了。
那他是怎么帮我们实例化的呢,这个就离不开我们的核心BeanFactory了也就是Bean工厂,我们看看他有那些实现
public interface BeanFactory {
String FACTORY_BEAN_PREFIX = "&";
Object getBean(String var1) throws BeansException;
<T> T getBean(String var1, Class<T> var2) throws BeansException;
Object getBean(String var1, Object... var2) throws BeansException;
<T> T getBean(Class<T> var1) throws BeansException;
<T> T getBean(Class<T> var1, Object... var2) throws BeansException;
boolean containsBean(String var1);
boolean isSingleton(String var1) throws NoSuchBeanDefinitionException;
boolean isPrototype(String var1) throws NoSuchBeanDefinitionException;
boolean isTypeMatch(String var1, ResolvableType var2) throws NoSuchBeanDefinitionException;
boolean isTypeMatch(String var1, Class<?> var2) throws NoSuchBeanDefinitionException;
Class<?> getType(String var1) throws NoSuchBeanDefinitionException;
String[] getAliases(String var1);
}
他长这样,这个就是Spring的核心,Spring是喜欢谁就Bean谁,我们所有的对象最终都会放到他里面去,然后读取的时候,再从他里面拿,但是并不是直接从它里面拿,一般我们都是通过Context上下文里面拿,因为上下文包含他。怎么包含的
public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory, MessageSource, ApplicationEventPublisher, ResourcePatternResolver {
String getId();
String getApplicationName();
String getDisplayName();
long getStartupDate();
ApplicationContext getParent();
AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException;
}
我们看到这里面有一个
AutowireCapableBeanFactory 然后看看他,他继承了Bean工厂
public interface AutowireCapableBeanFactory extends BeanFactory {
int AUTOWIRE_NO = 0;
int AUTOWIRE_BY_NAME = 1;
int AUTOWIRE_BY_TYPE = 2;
int AUTOWIRE_CONSTRUCTOR = 3;
-----------
}
所以我们一般看到的都是这种
ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
ClassName clazz =(ClassName)ctx.getBean("beanName");
而上下文就是通过配置文件获取的了,这就是SpringIoc的简单的叙述。