spring学习总结(一)

一、spring框架概述

spring是一个开源免费的框架,是基于java平台为了解决企业应用开发的复杂性而创建的。spring是各个功能是模块化的,所以你不使用的功能可以舍弃掉,只使用其中的部分功能。

1、spring是一款轻量级的企业级框架,所以不需要你实现或继承spring中的接口和类,各个逻辑代码不依赖于spring框架本身,你可以只专注于本身本身,所以你可以很轻松的把spring分离开来。

2、控制反转IOC(Inversion of Control):是一种设计思想,反转资源获取的方向,通过依赖注入DI(Dependency Injection)的方式来实现;传统的资源查找方式要求组件向容器发起请求查找资源. 作为回应, 容器适时的返回资源. 而应用了 IOC 之后, 则是容器主动地将资源推送给它所管理的组件, 组件所要做的仅是选择一种合适的方式来接受资源. 这种行为也被称为查找的被动形式,使用IOC时,一个对象依赖的其它对象会通过被动的方式传递进来,而不是这个对象自己创建或者查找依赖对象;即组件以一些预先定义好的方式(例如: setter 方法)接受来自如容器的资源注入.

3、面向切面AOP(Aspect-Oriented Programming,面向方面编程):

二、spring的组成

Spring 框架是一个分层架构,由 7 个定义良好的模块组成。Spring 模块构建在核心容器之上,核心容器定义了创建、配置和管理 bean 的方式

组成 Spring 框架的每个模块(或组件)都可以单独存在,或者与其他一个或多个模块联合实现。每个模块的功能如下:

  • 核心容器:核心容器提供 Spring 框架的基本功能。核心容器的主要组件是 BeanFactory,它是工厂模式的实现。BeanFactory 使用控制反转(IOC) 模式将应用程序的配置和依赖性规范与实际的应用程序代码分开。
  • Spring 上下文:Spring 上下文是一个配置文件,向 Spring 框架提供上下文信息。Spring 上下文包括企业服务,例如 JNDI、EJB、电子邮件、国际化、校验和调度功能。
  • Spring AOP:通过配置管理特性,Spring AOP 模块直接将面向方面的编程功能集成到了 Spring 框架中。所以,可以很容易地使 Spring 框架管理的任何对象支持 AOP。Spring AOP 模块为基于 Spring 的应用程序中的对象提供了事务管理服务。通过使用 Spring AOP,不用依赖 EJB 组件,就可以将声明性事务管理集成到应用程序中。
  • Spring DAO:JDBC DAO 抽象层提供了有意义的异常层次结构,可用该结构来管理异常处理和不同数据库供应商抛出的错误消息。异常层次结构简化了错误处理,并且极大地降低了需要编写的异常代码数量(例如打开和关闭连接)。Spring DAO 的面向 JDBC 的异常遵从通用的 DAO 异常层次结构。
  • Spring ORM:Spring 框架插入了若干个 ORM 框架,从而提供了 ORM 的对象关系工具,其中包括 JDO、Hibernate 和 iBatis SQL Map。所有这些都遵从 Spring 的通用事务和 DAO 异常层次结构。
  • Spring Web 模块:Web 上下文模块建立在应用程序上下文模块之上,为基于 Web 的应用程序提供了上下文。所以,Spring 框架支持与 Jakarta Struts 的集成。Web 模块还简化了处理多部分请求以及将请求参数绑定到域对象的工作。
  • Spring MVC 框架:MVC 框架是一个全功能的构建 Web 应用程序的 MVC 实现。通过策略接口,MVC 框架变成为高度可配置的,MVC 容纳了大量视图技术,其中包括 JSP、Velocity、Tiles、iText 和 POI。

三、IOC容器

IOC:Inversion of Control,控制反转。指的是对象的创建权反转(交给)给Spring,其作用是实现了程序的解耦合。也可这样解释:获取对象的方式变了。对象创建的控制权不是“使用者”,而是“框架”或者“容器”。 用更通俗的话来说,IOC就是指对象的创建,并不是在代码中用new操作new出来的,而是通过Spring进行配置创建的。其底层实现原理是XML配置文件+SAX解析+工厂设计模式。

(一)使用xml配置的方式来实现IOC

IUserDao.java:

package com.test.spring01;

public interface IUserDao {
	/**
	 * 添加用户
	 */
	public void addUser();
}

UserDao.java

package com.test.spring01;

public class UserDao implements IUserDao{

	@Override
	public void addUser() {
		System.out.println("添加了一个用户");
	}

}

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:util="http://www.springframework.org/schema/util"
	xmlns:p="http://www.springframework.org/schema/p"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">
	
	<bean id="userDao" class="com.test.spring01.UserDao"></bean>
	
</beans>

main.java 

package com.test.spring01;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {
	@Test
	public void test1() {
		//获取IOC容器对象
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
		//从容器中获取userDao
		IUserDao userDao = (IUserDao) applicationContext.getBean("userDao");
		//调用业务方法
		userDao.addUser();
	}
}

运行结果:

1.通过有参构造函数与setting的方式创建对象 

Employee.java

package com.test.spring02;

public class Employee {
	private String name;
	private String sex;
	private Double salary;
	private Department dept;
	
	public Employee() {
		super();
	}
	
	public Employee(String name, String sex, Double salary, Department dept) {
		super();
		this.name = name;
		this.sex = sex;
		this.salary = salary;
		this.dept = dept;
	}

    //此处省略getter与setter方法

	@Override
	public String toString() {
		return "Employee [name=" + name + ", sex=" + sex + ", salary=" + salary + ", dept=" + dept + "]";
	}
}

Department.java

package com.test.spring02;

import java.util.List;
import java.util.Map;
import java.util.Set;

public class Department {
	private String name;
	private String deptno;
	private List<Employee> list;
	private Set<Employee> set;
	private Map<String, Employee> map;
	public Department() {
		super();
	}
	
	public Department(String name, String deptno) {
		super();
		this.name = name;
		this.deptno = deptno;
	}	
	
	public Department(String name, String deptno, List<Employee> list, Set<Employee> set, Map<String, Employee> map) {
		super();
		this.name = name;
		this.deptno = deptno;
		this.list = list;
		this.set = set;
		this.map = map;
	}	
	//此处省略getter与setter方法
	@Override
	public String toString() {
		return "Department [name=" + name + ", deptno=" + deptno + "]";
	}
	
}

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:util="http://www.springframework.org/schema/util"
	xmlns:p="http://www.springframework.org/schema/p"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">
	<!-- 1、根据构造器参数的类型 -->
	<bean id="employee1" class="com.test.spring02.Employee">
		<constructor-arg type="java.lang.String" value="张三" />
		<constructor-arg type="java.lang.String" value="男" />
		<constructor-arg type="java.lang.Double" value="100.0" />
		<constructor-arg type="com.test.spring02.Department" ref="dept" />
	</bean>
 
	<!-- 2、根据索引index注入 -->
	<bean id="employee2" class="com.test.spring02.Employee">
		<constructor-arg index="0" value="李四" />
		<constructor-arg index="1" value="女" />
		<constructor-arg index="2" value="100.0" />
		<constructor-arg index="3" ref="dept" />
	</bean>
	<!-- 3、根据参数名称注入 -->
	<bean id="employee3" class="com.test.spring02.Employee">
		<constructor-arg name="name" value="王五" />
		<constructor-arg name="sex" value="男" />
		<constructor-arg name="salary" value="100.0" />
		<constructor-arg name="dept" ref="dept" />
	</bean>
	<!-- 4、根据setting的方式注入 -->
	<bean id="dept" class="com.test.spring02.Department">
		<property name="name" value="人事部" />
		<property name="deptno" value="0x0001" />
	</bean>
	
	<!-- 5.使用内部bean的方式注入 -->
	<bean id="employee4" class="com.test.spring02.Employee">
		<property name="name" value="赵六"></property>
		<property name="sex" value="男"></property>
		<property name="salary" value="100.0"></property>
		<property name="dept">
			<!-- 只能在内部使用,可以不写id值 -->
			<bean id="dept" class="com.test.spring02.Department">
				<property name="name" value="人事部" />
				<property name="deptno" value="0x0001" />
			</bean>
		</property>
	</bean>
	<!-- 6.使用级联的方式注入 -->
	<bean id="employee5" class="com.test.spring02.Employee">
		<property name="name" value="陈七"></property>
		<property name="sex" value="男"></property>
		<property name="salary" value="100.0"></property>
		<property name="dept">
			<bean id="dept" class="com.test.spring02.Department">
				<property name="name" value="人事部" />
			</bean>
		</property>
		<!-- 级联属性赋值,注意:属性需要先初始化后才可以为级联属性赋值,否为会有异常 -->
		<property name="dept.deptno" value="0x00001"></property>
	</bean>
	<!-- 通过p命名空间为bean的属性赋值,需导入p命名空间 -->
	<bean id="employee6" class="com.test.spring02.Employee" p:name="吴八" p:sex="男" p:salary="100.0" p:dept-ref="dept"></bean>
	
	<!-- 7.注入集合属性 -->
	<bean id="dept2" class="com.test.spring02.Department">
		<property name="name" value="人事部" />
		<property name="deptno" value="0x0001" />
		<!-- 注入list集合 -->
		<property name="list">
			<list>
				<ref bean="employee1"/>
				<bean id="employee3" class="com.test.spring02.Employee">
					<constructor-arg name="name" value="王五" />
					<constructor-arg name="sex" value="男" />
					<constructor-arg name="salary" value="100.0" />
					<constructor-arg name="dept" ref="dept" />
				</bean>
			</list>
		</property>
		<!-- 注入set集合 -->
		<property name="set" ref="set"></property>
		<!-- 注入map集合 -->
		<property name="map">
			<map>
				<entry key="emp1" value-ref="employee1"></entry>
				<entry key="emp2" value-ref="employee2"></entry>
			</map>
		</property>
	</bean>
	
	<!-- 配置单例的集合bean,以供多个bean进行引用,需要导入util命名空间 -->
	<util:set id="set">
		<ref bean="employee1"/>
		<ref bean="employee2"/>
	</util:set>
	
</beans>

Main.java

package com.test.spring01;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.test.spring02.Department;
import com.test.spring02.Employee;

public class Main {
	@Test
	public void test2() {
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
		Employee employee1 = (Employee) applicationContext.getBean("employee1");
		Employee employee2 = (Employee) applicationContext.getBean("employee2");
		Employee employee3 = (Employee) applicationContext.getBean("employee3");
		Employee employee4 = (Employee) applicationContext.getBean("employee4");
		Employee employee5 = (Employee) applicationContext.getBean("employee5");
		Employee employee6 = (Employee) applicationContext.getBean("employee6");
		Department dept2 = (Department)applicationContext.getBean("dept2");
		System.out.println(employee1);
		System.out.println(employee2);
		System.out.println(employee3);
		System.out.println(employee4);
		System.out.println(employee5);
		System.out.println(employee6);
		System.out.println(dept2 +" list: "+ dept2.getList());
		System.out.println(dept2 +" set: "+ dept2.getSet());
		System.out.println(dept2 +" map: "+ dept2.getMap());
		
	}
}

运行结果:

注意事项:

  1. bean中的id为唯一标识,不可重复
  2. 使用构造函数的方式创建对象,对应的类中需要有对应的构造函数
  3. 若字面值中包含特殊字符, 则可以使用 DCDATA 来进行赋值. (![CDATA[<ATARZA>])
  4. 如果要为一个属性赋值为null,可以使用<null/>进行赋值
  5. 若一个 bean 有多个构造器,可以根据 index 和 value 进行更加精确的定位
  6. 级联属性赋值时先初始化后才可以为级联属性赋值,否为会报空指针异常

2.通过工厂方法创建对象

  • 通过静态工厂方法创建对象

User.java

package com.test.spring06;

public class User {
	private String name;
	private int age;
	public User() {
		super();
	}
	public User(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
        //此处省略getter与setter方法
	@Override
	public String toString() {
		return "User [name=" + name + ", age=" + age + "]";
	}
	
}

StaticUserFactory.java

package com.test.spring06;

import java.util.HashMap;
import java.util.Map;

public class StaticUserFactory {
	
	private static Map<String, User> users = new HashMap<String, User>();
	static {
		users.put("Jack",new User("Jack",17));
		users.put("Rose",new User("Rose",17));
	}
	public static User getUser(String name) {
		return users.get(name);
	}
}

applicationContext-factory.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:util="http://www.springframework.org/schema/util"
	xmlns:p="http://www.springframework.org/schema/p"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">
		
		<!-- 通过静态工厂方法来配置bean -->
		<!-- 
			class 属性:只想静态工厂方法的全类名
			factory-method:指向静态工厂方法的方法名
			constructor-arg:静态工厂方法需要传入参数
		 -->
		<bean id="user" class="com.test.spring06.StaticUserFactory" factory-method="getUser">
			<constructor-arg value="Jack"></constructor-arg>
		</bean>
</beans>

Main.java

package com.test.spring06;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {
	
	public static void main(String[] args) {
		
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext-factory.xml");
		User user = (User) applicationContext.getBean("user");
		System.out.println(user);
	}
}

得到结果:

  • 通过实例工厂方法获取对象

User.java

package com.test.spring06;

public class User {
	private String name;
	private int age;
	public User() {
		super();
	}
	public User(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
        //此处省略getter与setter方法
	@Override
	public String toString() {
		return "User [name=" + name + ", age=" + age + "]";
	}
	
}

InstanceUserFactory.java

package com.test.spring06;

import java.util.HashMap;
import java.util.Map;

public class InstanceUserFactory {
	
	private Map<String, User> users;
	
	public InstanceUserFactory() {
		users = new HashMap<String, User>();
		users.put("Jack",new User("Jack",17));
		users.put("Rose",new User("Rose",17));
	}
	public User getUser(String name) {
		return users.get(name);
	}
}

applicationContext-factory.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:util="http://www.springframework.org/schema/util"
	xmlns:p="http://www.springframework.org/schema/p"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">
		
		<!-- 配置工厂的实例 -->
		<bean id="userFactory" class="com.test.spring06.InstanceUserFactory"></bean>
		<!-- 通过实例公共方法来配置bean -->
		<bean id="user" factory-bean="userFactory" factory-method="getUser">
			<constructor-arg value="Rose"></constructor-arg>
		</bean>
</beans>

Main.java

package com.test.spring06;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {
	
	public static void main(String[] args) {
		
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext-factory.xml");
		User user = (User) applicationContext.getBean("user");
		System.out.println(user);
	}
}

得到结果:

猜你喜欢

转载自blog.csdn.net/qq_37776015/article/details/81904287