spring框架-认识spring框架(一)
上一章提到的一些概念,本章会详细解读
IoC(Inversion of Control)控制反转,包含了两个方面:一、控制。二、反转
类与类依赖关系交给容器处理。IoC不是一种技术,只是一种思想,一个重要的面向对象编程的法则,它能指导我们如何设计出松耦合、更优良的程序。
IOC不够开门见山,于是Martin Fowler提出了DI(dependency injection)依赖注入来替代IoC,即让调用类对某一接口实现类的依赖关系由第三方(容器或协作类)注入,以移除调用类对某一接口实现类的依赖。
IOC有两种方式:DI(依赖注入)和DL (依赖查找)
程序提供查找方式,交给容器去查找(回调函数)
容器提供回调接口和上下文环境给组件。EJB和Apache Avalon都使用这种方式
下面代码展示了基于JNDI实现的依赖查找机制。
public class MyBusniessObject{
private DataSource ds;
private MyCollaborator myCollaborator;
public MyBusnissObject(){
Context ctx = null;
try{
ctx = new InitialContext();
ds = (DataSource) ctx.lookup(“java:comp/env/dataSourceName”);
myCollaborator =
(MyCollaborator) ctx.lookup(“java:comp/env/myCollaboratorName”);
}……
但是日常开发中,EJB类似的已经很少用到了,所以很多同学没听过DL(依赖查找),这很正常,大家更熟悉的是DI(依赖注入)。
不过这两个查找大家应该用过:
直接从 BeanFactory 中取出这个 bean 就可以了,常用的就是@Qualifier
常用的就是@autowire
如果容器中存在一个与指定属性类型相同的bean,那么将与该属性自动装配。如果存在多个该类型的bean,那么将会抛出异常
简单的理解就是通过类名去匹配
一个对象需要另外一个对象时,无需在代码中创建被调用者,而是依赖于外部容器,由外部容器创建后传递给程序
用图例说明一下,传统程序设计如下图1,都是主动去创建相关对象然后再组合起来:
当有了IoC/DI的容器后,在客户端类中不再主动去创建这些对象了,如图2所示
IOC容器其实就是一个大工厂,它用来管理我们所有的对象以及依赖关系。
ApplicationContext这个大家就很熟悉了吧,spring绝大部分应用都是使用ApplicationContext
BeanFactory 可以理解为含有bean集合的工厂类。BeanFactory 包含了种bean的定义,以便在接收到客户端请求时将对应的bean实例化。
BeanFactory还能在实例化对象的时生成协作类之间的关系。此举将bean自身与bean客户端的配置中解放出来。BeanFactory还包含了bean生命周期的控制,调用客户端的初始化方法(initialization methods)和销毁方法(destruction methods)。
applicationcontext是beanFactory的子接口,拥有BeanFactory的所有功能,但applicationcontext在此基础上还提供了其他的功能。
以下是三种较常见的 ApplicationContext 实现方式:
1、ClassPathXmlApplicationContext:从classpath的XML配置文件中读取上下文,并生成上下文定义。应用程序上下文从程序环境变量中取得
ApplicationContext context = new ClassPathXmlApplicationContext(“bean.xml”);
2、FileSystemXmlApplicationContext :由文件系统中的XML配置文件读取上下文。ApplicationContext context = new FileSystemXmlApplicationContext(“bean.xml”);
3、XmlWebApplicationContext:由Web应用的XML文件读取上下文。
Spring Bean的生命周期简单易懂。在一个bean实例被初始化时,需要执行一系列的初始化操作以达到可用的状态。同样的,当一个bean不在被调用时需要进行相关的析构操作,并从bean容器中移除。
Spring bean factory 负责管理在spring容器中被创建的bean的生命周期。Bean的生命周期由两组回调(call back)方法组成。
Spring框架提供了以下四种方式来管理bean的生命周期事件:
使用customInit()
和 customDestroy()
方法管理
bean
生命周期的代码样例如下:
<beans>
<bean id="demoBean" class="com.somnus.task.DemoBean" init-method="customInit" destroy-method="customDestroy">
</bean>
</beans>
Spring4.x开始IOC容器装配Bean有4种方式:
日常开发中,常用到的是XML配置+注解。
剩下的两种有兴趣的可以自行百度+google
依赖注入的方式有3种方式:
setter()
方法注入ObjectCurrentlyInCreationException异常,因为在B对象被创建之前A对象是不能被创建的,反之亦然。所以Spring用设值注入的方法解决了循环依赖的问题,因对象的设值方法是在对象被创建之前被调用的。
Spring容器中的bean可以分为5个范围。所有范围的名称都是自说明的,但是为了避免混淆,还是让我们来解释一下:
使用3,4,5作用域的,需要手动设置代理
使用bean元素的autowire属性来指定Bean定义的自动装配,共有5中模式:
注解注入就是用注解标签的方式来替换掉我们 xml 配置文件里面 bean 的注册和依赖
@Component
用于类上
所有的类上面都可以这么写,通用注解,这是不规范的写法,哈哈哈
@Repository
用于类上
这个注解主要是声明 dao 的类组件
@Service
这个注解主要是声明 service 服务类
@Controller
主要是声明控制类 (springmvc/struts2 action/controller)
@Resource
用于类内
javaEE 的注解 ,默认是以 byName 方式注入,byName 找不到的话,再用 byType 去匹配
效果跟Autowired一样,查找顺序相反
@Resource有两个属性是比较重要的,分是name和type,Spring将@Resource注解的name属性解析为bean的名字,而type属性则解析为bean的类型。所以如果使用name属性,则使用byName的自动注入策略,而使用type属性时则使用byType自动注入策略。如果既不指定name也不指定type属性,这时将通过反射机制使用byName自动注入策略。
@Autowired
用于类内
spring 的注解,默认是以 byType 注入,-如果有多个实现类,他再用 byName 的方式(@Qualifier)去匹配
效果跟Resource一样,查找顺序相反
Autowired和Qualifier一起用,
eg:
@Autowired
@Qualifier(value = "TestService2")
private TestService testService;
//实现类
@Service("TestService1")
public class TestServiceImpl implements TestService {...}
//实现类
@Service("TestService2")
public class TestServiceImpl implements TestService {...}
@Qualifier
spring的注解,可以指定实现的方法名称
@Scope
bean的作用域,可以查看上面的概念,这里就不再重复了
借鉴了其他博主的思路:会整理出Spring思维导图出来,等AOP写好一并放出来。
今天的spring介绍就写到这里,再见!
参考资料:
https://my.oschina.net/u/3777556/blog/1816921--Spring IOC知识点一网打尽!
https://www.zhihu.com/question/48427693?sort=created--怎么回答面试官:你对Spring的理解
https://www.cnblogs.com/liangyihui/p/5917773.html--最全的Spring面试题和答案
https://blog.csdn.net/sunqingzhong44/article/details/51983620--spring笔记——bean自动装配的5种模式(autowrite属性)
联系客服