Spring框架核心技术--IOC容器
2016-10-03 09:49
645 查看
Spring框架核心技术–IOC容器
Spring框架核心技术IOC容器概述
Spring框架
专业术语详解
Spring框架六大模块功能
Spring开发步骤
bean对象创建的细节
SpringIOC容器
对象依赖关系
概述
简单来说Spring就是处理对象的创建、以及对象的依赖关系,之前的解决方案我们都是采用entity、dao、service、servlet、Jsp分开写,并且注意这些包之间的依赖关系,现在的Spring框架使得这件事情变得十分的简单,这是功能最强大的一个框架。Spring框架主页:www.springsource.org 。Spring框架
Spring框架,可以解决对象创建以及对象之间的依赖关系的一种框架,且可以和其它框架一起使用,包括Spring和Struts、Spring和Hibernate框架的整合,总的来说,Spring框架是一个起到整合(粘合)作用的框架。[b]专业术语详解[/b]
组件/框架设计
侵入式设计
引入了框架,对现有的类的结构有影响,即需要实现或者继承某些特定的类,Struts是侵入式设计框架。
非侵入式设计
引入了框架,对现有的类结构没有影响,我们在设计时一般都是使用非侵入式设计,Hibernate是非侵入式的设计框架,Spring框架也是非侵入式设计框架。
控制反转 Inversion on Control
需要什么就创建什么,这属于需求驱动型,这是”控制正转”,而将对象的创建交给外部容器完成,这叫作控制反转,想要拿到别人创建的对象,必须有一个可以获取该对象的公用的接口。控制反转主要是用来解决对象创建的问题(对象创建交给其它容器)
依赖注入
处理对象的依赖关系,先有控制反转后才出现依赖注入。解决对象创建完之后,对象关系的处理就是依赖注入(通过set方法依赖注入)
AOP 面向切面编程
切面,简单来说可以理解为一个类,由很多重复代码形成的类。举例来说包括:事务、日志、权限等。
[b]Spring框架六大模块功能[/b]
[b]Spring开发步骤[/b]
下载Spring的源代码,并将其中的jar包导入到项目中
由于项目中的jar包很多,所以导入的方法与之前在小型项目中新建lib文件夹并将jar包复制进行的方法不一样,采用的方法为:新建Java项目,右键–>properties–>Java Build Path–>Add Libray–>User Libray–>next–>User Libraries–>New–>输入要新建的Library的名字,完成之后点击确定–>Add External JARs,将外部的Spring的Jar包导入到项目中,一般情况下需要建立下面的几个Jar包,要添加的Jar包见附件。
书写Spring mvc核心配置文件
该文件通常被命名为applicationConetxt.xml或者bean.xml,首先需要在该xml文件中添加schema部分,该部分的代码如下:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> </beans>
得到容器对象
package com.jpzhutech.spring; import org.junit.Test; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.xml.XmlBeanFactory; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; public class App { //通过工厂类得到容器创建的对象 @Test public void testIOC1() throws Exception{ //创建对象 //User user = new User(); //在Spring之前创建对象的方法 //现在将对象的创建交给Spring的IOC容器 Resource resource = new ClassPathResource("com/jpzhutech/spring/applicationContext.xml"); //在这里一定要注意导入spring的包 //创建容器对象(bean工厂),也称为IOC容器=工厂类+applicationContext.xml文件 BeanFactory factory = new XmlBeanFactory(resource); //得到容器创建的对象 User user = (User)factory.getBean("user"); System.out.println(user); } //直接得到IOC容器对象,该方法比较方便,在后续的ssm学习中,采用该方法创建对象 @Test public void testIOC2() throws Exception{ //得到容器对象 ApplicationContext applicationContext = new ClassPathXmlApplicationContext("com/jpzhutech/spring/applicationContext.xml"); //从容器中获取bean User user = (User)applicationContext.getBean("user"); System.out.println(user); } }
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- IOC容器的配置:要将所有要创建的对象都配置在这里 --> <bean id="user" class="com.jpzhutech.spring.User"> </bean> </beans>
//注意该类没有构造函数,创建对象时使用Spring的特性去创建 package com.jpzhutech.spring; public class User { private int id; private String name; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
[b]bean对象创建的细节[/b]
Spring为我们默认创建的对象时单例的,但是可以在xml中配置单例或者多例模式。多例模式只有在对象需要的时候才创建对象,而对于单例模式,在容器创建之前就已经创建好了对象,整个应用只有这一个对象,这是二者的区别。
对象创建能否写死?不能,Spring在配置文件中写入要创建的对象,随时进行更改
对象创建的细节
对象数量
action 多个 维护成员变量 此时采用prototype参数值
service 一个 不需要维护公共变量 此时采用singleton参数值
dao 一个 不需要维护公共变量 此时采用singleton参数值
创建时间
action 访问的时候创建 采用prototype参数值
service 启动的时候创建 采用singleton参数值
dao 启动的时候创建 采用singleton参数值
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- IOC容器的配置:要将所有要创建的对象都配置在这里,默认情况下创建的对象是单例的,但是可以使用scope参数来指定,其中scope的取值为singleton(单例)/prototype(多例) --> <!-- lazy-init参数用于指定是否使用懒加载,该参数只对单例有效--> <bean id="user" class="com.jpzhutech.spring.User" scope="prototype" lazy-init="default" > </bean> </beans>
[b]SpringIOC容器[/b]
SpringIOC容器是Spring的核心内容,作用是用于对象的创建,解决对象之间的依赖关系。
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- IOC容器的配置:要将所有要创建的对象都配置在这里,默认情况下创建的对象是单例的,但是可以使用scope参数来指定,其中scope的取值为singleton(单例)/prototype(多例) --> <!-- lazy-init参数用于指定是否使用懒加载,该参数只对单例有效--> <!-- 使用无参数构造函数 --> <bean id="user1" class="com.jpzhutech.spring.User" scope="prototype" lazy-init="default" > </bean> <!-- 使用带参数构造器创建对象 --> <bean id="user2" class="com.jpzhutech.spring.User"> <constructor-arg value="100" index="0" type="int" ></constructor-arg> <constructor-arg value="jpzhu" index="1" type="java.lang.String" ></constructor-arg> </bean> <!-- 创建一个字符串,值是Jack --> <bean id="str" class="java.lang.String" scope="singleton"> <constructor-arg index="0" value="Jack" type="String"></constructor-arg> </bean> <bean id="user3" class="com.jpzhutech.spring.User"> <constructor-arg value="100" index="0" type="int" ></constructor-arg> <constructor-arg ref="str" index="1" type="java.lang.String" ></constructor-arg> <!-- 引用上述创建的字符串 --> </bean> <!-- 工厂实例方法创建对象 --> <!-- 首先创建工厂类的实例 --> <bean id="factory" class="com.jpzhutech.spring.ObjectFactory"></bean> <!-- 使用工厂对象的实例方法创建对象 --> <bean id="user4" factory-bean="factory" factory-method="getInstance"></bean> <!-- 工厂类的静态方法创建对象,静态方法不需要创建工厂实例,并且静态方法中含有参数--> <!-- class指定静态方法所在的类,factory-method指定静态方法名 --> <bean id="user5" factory-method="getInstance_static" class="com.jpzhutech.spring.ObjectFactory"> <constructor-arg value="101" type="int"></constructor-arg> <constructor-arg value="jiamin" type="String"></constructor-arg> </bean> </beans>
Application.java
package com.jpzhutech.spring; import org.junit.Test; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.xml.XmlBeanFactory; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; @SuppressWarnings("deprecation") public class App { //通过工厂类得到容器创建的对象 @Test public void testIOC1() throws Exception{ //创建对象 //User user = new User(); //在Spring之前创建对象的方法 //现在将对象的创建交给Spring的IOC容器 Resource resource = new ClassPathResource("com/jpzhutech/spring/applicationContext.xml"); //在这里一定要注意导入spring的包 //创建容器对象(bean工厂),也称为IOC容器=工厂类+applicationContext.xml文件 BeanFactory factory = new XmlBeanFactory(resource); //得到容器创建的对象 User user = (User)factory.getBean("user"); System.out.println(user); } //直接得到IOC容器对象,该方法比较方便,在后续的ssm学习中,采用该方法创建对象 @Test public void testIOC2() throws Exception{ //得到容器对象 ApplicationContext applicationContext = new ClassPathXmlApplicationContext("com/jpzhutech/spring/applicationContext.xml"); //从容器中获取bean User user1 = (User)applicationContext.getBean("user1"); User user2 = (User)applicationContext.getBean("user2"); //使用带参数的构造函数 User user3 = (User)applicationContext.getBean("user3"); //使用带参数的构造函数 System.out.println(user1); System.out.println(user2.getName()); //System.out.println((String)applicationContext.getBean("str")); //使用在配置文件中创建的对象 System.out.println(user3.getName()); User user4 =(User)applicationContext.getBean("user4"); System.out.println("user4对象为:"+user4); User user5 = (User)applicationContext.getBean("user5"); System.out.println("user5对象为:"+user5); } }
User.java
package com.jpzhutech.spring; public class User { private int id; private String name; public User() { super(); } public User(int id, String name) { super(); this.id = id; this.name = name; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "User [id=" + id + ", name=" + name + "]"; }
ObjectFactory.java
package com.jpzhutech.spring; public class ObjectFactory { //工厂实例方法创建对象 public User getInstance(){ return new User(); } //工厂静态方法创建对象 public static User getInstance_static(int id , String name){ return new User(id,name); } }
[b]对象依赖关系[/b]
对象依赖关系解决的问题是如何给Spring中的属性赋值,属性赋值的方法和代码测试如下
通过构造函数
通过set方法给属性注入值
内部bean,逻辑较为复杂,一般不推荐使用
p名称空间,该方法优化leset方法给属性注入值
自动装配,该方法一般不用了解即可
注解
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- 对象属性赋值 --> <!-- 根据带参数的构造函数 --> <bean id="user1" class="com.jpzhutech.property.User" lazy-init="default" > <constructor-arg value="10" index="0" type="int"></constructor-arg> <constructor-arg value="jpzhu" index="1" type="String" ></constructor-arg> </bean> <!-- 通过set方法给对象属性注入值 --> <!-- 每个实体都是一个标准的Java Bean,所以其对于每个属性一定都是私有的并且带有get和set方法,这样基于可以通过set注入属性值 --> <bean id="user2" class="com.jpzhutech.property.User" > <property name="id" value="101"></property> <property name="name" value="jiamin"></property> </bean> <!-- 内部bean --> <!-- 在类之间存在相互的依赖关系,存在对象之间的层层嵌套关系,此时内部bean十分的有用,写的很漂亮,但是逻辑容易出现错误 --> <bean id="user3" class="com.jpzhutech.property.User" > <property name="id" value="10000"></property> <!-- 简单数据类型直接根据属性进行赋值 --> <property name="name"> <!-- 引用数据类型,使用内部bean的形式进行赋值 --> <bean id = "str" class="java.lang.String" > <constructor-arg value="Jack"></constructor-arg> </bean> </property> </bean> <!-- p名称空间给对象属性注入值,在Spring 3.0以上版本才支持该特性,在本例中p:name-ref="string"引用了前面的bean对象,p名称空间的本质还是set方法注入值--> <bean id="string1" class="java.lang.String" > <constructor-arg value="Rose"></constructor-arg> </bean> <bean id="user4" class="com.jpzhutech.property.User" p:name-ref="string1"></bean> <!-- 自动装配给对象属性注入值,自动装配了解即可,一般不用这种方式--> <bean id="name" class="java.lang.String" > <constructor-arg value="Fuck"></constructor-arg> </bean> <bean id="user5" class="com.jpzhutech.property.User" autowire="byName"></bean> <!-- 注解方式给对象属性注入值,注解的方式可以简化Spring的配置 --> <!-- 使用注解首先要引入context名称空间,接着开启注解扫描,接下来就能使用注解了,通过注解的方式把对象引入IOC容器 --> <context:component-scan base-package="com.jpzhutech" ></context:component-scan> </beans>
App.java
package com.jpzhutech.property; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class App { private ApplicationContext applicationContext; @Test public void testProperty() throws Exception{ //创建IOC容器 applicationContext = new ClassPathXmlApplicationContext("com/jpzhutech/property/applicationContext.xml"); //user1通过构造函数创建对象 User user1 = (User)applicationContext.getBean("user1"); System.out.println("id:"+user1.getId()+" name:"+user1.getName() ); //user2通过set方法为属性注入值 User user2 = (User)applicationContext.getBean("user2"); System.out.println("id:"+user2.getId()+" name:"+user2.getName()); //user3内部bean构造对象,逻辑容易出错 User user3 = (User)applicationContext.getBean("user3"); System.out.println("id:"+user3.getId()+" name:"+user3.getName()); //利用p名称空间构造对象 User user4 = (User)applicationContext.getBean("user4"); System.out.println("id:"+user4.getId()+" name:"+user4.getName()); //自动装配 User user5 = (User)applicationContext.getBean("user5"); System.out.println("id:"+user5.getId()+" name:"+user5.getName()); //注解方式给属性注入值 } }
User.java
package com.jpzhutech.property; import javax.annotation.Resource; import org.springframework.stereotype.Component; @Component public class User { private int id; @Resource //这种注解方式是根据类型进行查找的,必须要确保该类型只有一个变量,所以我们一般情况还是要明确给出其中参数的 private String name; public User() { super(); } public User(int id, String name) { super(); this.id = id; this.name = name; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "User [id=" + id + ", name=" + name + "]"; } }
相关文章推荐
- Spring框架参考文档-核心技术-IoC容器
- Spring框架的AOP/IOC/容器核心原理实例详解
- Spring框架的ioc容器核心功能模拟实现
- Spring 核心技术 IoC容器(一)
- Spring核心技术原理-(4)-三条路线告诉你如何掌握Spring IoC容器的核心原理
- Spring核心技术原理-(4)-三条路线告诉你如何掌握Spring IoC容器的核心原理
- Spring核心技术(一)——IoC容器和Bean简介
- Spring核心技术IoC容器(四)
- Spring核心技术IoC容器(七)
- Spring技术内幕2Spring Framework的核心:IoC容器的实现
- Spring核心技术IoC容器(八)
- Spring技术核心内幕 读书笔记--IOC容器的实现小结
- Spring 核心技术IoC容器(二)
- Spring核心技术IoC容器(五)
- Spring核心技术IoC容器(六)
- Spring 核心技术IoC容器 (三)
- Spring框架IOC容器和AOP解析
- Spring核心技术(十二)——基于Java的容器配置(二)
- 8-spring源码3.2.18解读+spring技术内幕(IOC容器的依赖注入(反射+递归调用))
- Tapestry最新版5.1.0.5教程(六):核心利器-IoC容器介绍