您的位置:首页 > 编程语言 > Java开发

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 + "]";
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息