Spring(1)
Spring是一个轻量级框架,不同于Django。
实际上5个要点:轻量级(零配置编程),面向bean(只需要写简单的bean),松耦合(利用AOP),万能胶(和主流框架可以集成),设计模式(重点!!!)。
通常提起spring想到的就是AOP和IOC
简单的说IOC(Inversion of Control)是一种设计思想,把你设计好的对象交给容器来进行管理,而不是传统的交由别的对象进行管理,控制了资源的获取(从本来的New获取,变成了现在的从容器中进行获取)。另外一个方面:把本来我需要之后进行new(我需要时候,去new),现在成为了我需要时候就注入(一个是从内到外,一个是从外到内)。容器帮我们进行了查找,注入,对象只是被动的接受了(当然也是因为需要)。
DI(Dependency Injection)依赖注入,组件之间依赖关系由容器在运行期决定,形象的说,即由容器动态的将某个依赖关系注入到组件之中。依赖注入的目的并非为软件系统带来更多功能,而是为了提升组件重用的频率,并为系统搭建一个灵活、可扩展的平台。通过依赖注入机制,我们只需要通过简单的配置,而无需任何代码就可指定目标需要的资源,完成自身的业务逻辑,而不需要关心具体的资源来自何处,由谁实现。
IOC和DI的区别:其实我个人感觉不是很大,一个是注入(但是也是因为需要,也存在依赖的关系)。
在日常开发中我认为可以把@service这种注解,看作是IOC因为,这仅仅是把东西交给了容器进行保管,而且把Autowrited可以看作是DI,它把东西又从容器中拿了出来,进行了注入。
把对象交由容器管理的方式有三种:注解,xml,configbean
容器既然接收了bean对象那么也可以进行管理。
1.控制对象的创建方式,xml(在<bean>元素中使用scope属性进行控制,scope="singleton"表示单例模式,scope="prototype"表示每次都是一个新的对象)
2.控制对象组件的初始化
在构造器中进行某些初始化操作 public class ExampleBean { public ExampleBean() { System.out.println("正在进行初始化操作。。。。"); } public void execute() { System.out.println("调用了execute方法"); } }
public static void main(String[] args) { String conf = "applicationContext.xml"; //创建容器对象 ApplicationContext ac = new ClassPathXmlApplicationContext(conf); //得到Example对象 ExampleBean e1 = ac.getBean("example",ExampleBean.class); ExampleBean e2 = ac.getBean("example",ExampleBean.class); System.out.println(e1 == e2); }
如果要对初始方法进行确认(修改)
<!-- 创建一个ExampleBean对象 -->
<bean id ="example" class="com.zlc.test.ExampleBean" scope="prototype" init-method = "init"></bean>
通过指定init-method方法就可以完成。
3.指定组件的销毁方法
<!-- 创建一个ExampleBean对象 --> <bean id ="example" class="com.zlc.test.ExampleBean" init-method = "init" destroy-method="destroy"> </bean>
public static void main(String[] args) { String conf = "applicationContext.xml"; //创建容器对象 AbstractApplicationContext ac = new ClassPathXmlApplicationContext(conf); //得到Example对象 ExampleBean e1 = ac.getBean("example",ExampleBean.class); ExampleBean e2= ac.getBean("example",ExampleBean.class); ac.close();//释放spring容器对象,它会自动调用单例的destroy方法。 }
注入方式有三种:构造器注入,setter注入,接口注入
1.构造器注入主要是依赖于构造方法去实现,构造方法可以是有参也可以是无参,我们在平常都是通过类的构造方法来创建类对象,以及给他赋值,同样Spring 也可以采用反射的方式,通过构造方法来完成注入注入(赋值),这就是构造器注入的原理,说了那么多我们就来看看代码的实现吧
public class Role { private int id; private String roleName; private String note; public Role(){} public Role(int id,String roleName, String note) { super(); this.id = id; this.roleName = roleName; this.note = note; } //setter,getter方法省略 }
applicationContext.xml文件
<bean id="Role" class="com.xiaojiang.Spring.Role">
<constructor-arg value="1" type="int"></constructor-arg>
<constructor-arg value="小江" type="java.lang.String"></constructor-arg>
<constructor-arg value="有点丑" type="java.lang.String"></constructor-arg>
</bean>
constructor-arg元素用于定义类构造方法的参数,其中type用于定义参数的类型,也可以使用index来定义参数的位置,而这里的value是用于设置值,以上的代码就是通过一个Spring去装配一个Bean。
2.setter注入
setter是Spring现在最主流的注入方式,它可以利用Java Bean 规范所定义set/get方法来完成注入,可读性灵活性高,它不需要使用构造器注入时出现的多个参数,它可以把构造方法声明成无参构造,再使用setter注入设置相对应的值,其实也是通过java反射技术去实现的.
首先要在类里面有get和set方法。然后在xml中进行配置
<bean id="Role" class="com.xiaojiang.Spring.Role">
<property name="id" value="1"><property>
<property name="roleName" value="小江"><property>
<property name="note" value="测试"><property>
</bean>
3.就是接口注入(其实和set注入没什么区别)
下面看看spingioc的源码(实现过程)
启动spring容器的例子
利用一个配置文件来启动spring容器![](https://img2020.cnblogs.com/blog/1898491/202007/1898491-20200711122518455-179219989.png)
从继承图看其实还是比较复杂的(比容器结构复杂多了)
我比较喜欢看源码时候先看javadoc
中央接口,为应用程序提供配置。 在应用程序运行时为只读,但如果实现支持,则可以重新加载。
ApplicationContext提供:
用于访问应用程序组件的Bean工厂方法,继承自org.springframework.beans.factory.ListableBeanFactory接口。
以通用方式加载文件资源的能力,继承自org.springframework.core.io.ResourceLoader接口。
将事件发布到注册的侦听器的能力,继承自ApplicationEventPublisher接口。
解决消息的能力,支持国际化。继承自MessageSource接口。
从父上下文继承。在后代上下文中的定义将始终优先。例如,这意味着整个Web应用程序都可以使用单个父上下文,而每个servlet都有自己的子上下文,而该子上下文独立于任何其他servlet的子上下文。
除了标准的org.springframework.beans.factory.BeanFactory生命周期功能之外,ApplicationContext实现还检测并调用 ApplicationContextAware bean以及 ResourceLoaderAware,ApplicationEventPublisherAware 和 MessageSourceAware Bean。
smartcat.994