一、spring概述
1、概述
- spring是一个开源框架,是2003年兴起的一个轻量级的Java开发框架
- spring的核心是控制反转(IOC)和面向切面(AOP)
- Spring是一个分层的JavaSE/EEfull-stack(一站式) 轻量级开源框架
- 一站式:只需要一个spring框架,就可以完成JavaEE的项目开发
2、javaEE开发分成三层结构
- WEB层:Spring MVC
- 业务层(Service层):Spring的Bean管理,Spring的事务管理
- 持久层(DAO层):Spring的JDBC模板,ORM模块用于整合其他的持久层框架
3、spring优点
- 方便解耦,简化开发
- Spring提供的IOC容器,可以将所有对象创建和依赖关系维护,交给Spring管理
- AOP编程的支持
- Spring提供面向切面编程,可以方便的实现对程序进行权限拦截、运行监控等功能
- 声明式事务的支持
- 只需要通过配置就可以完成对事务的管理,而无需手动编程
- 方便程序的测试
- Spring对Junit4支持,可以通过注解方便的测试Spring程序
- 方便集成各种优秀框架
- Spring不排斥各种优秀的开源框架,其内部提供了对各种优秀框架(如:Struts2、Hibernate、MyBatis、Quartz等)的直接支持
- 降低JavaEE API的使用难度
- Spring 对JavaEE开发中非常难用的一些API(JDBC、JavaMail、远程调用等),都提供了封装,使这些API应用难度大大降低
二、spring入门
1、下载spring
我们使用spring4.2.4
2、Spring目录结构
- docs -- API和开发规范
- libs -- jar包和源码
- schema -- 约束
3、引入Spring的开发包
4个核心+日志包
4、创建配置文件,添加约束
<?xml version="1.0" encoding="UTF-8"?>
<!-- spring 约束 -->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="userService" class="com.itheima.service.UserServiceImpl"
scope="singleton" init-method="init" destroy-method="destroy"></bean>
</beans>
5、入门案例
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.itheima.service.UserService;
public class TestSpring {
@Test
public void test() throws Exception {
// 创建spring工厂(默认读取src的配置文件)
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext(
"applicationContext.xml");// 初始化的时候,调用init方法
// 通过工厂获得类
UserService userService = (UserService) applicationContext.getBean("userService");
userService.sayHello();
applicationContext.close();// 关闭工厂的时候调用destroy方法
}
}
接口的实现类
public class UserServiceImpl implements UserService {
@Override
public void sayHello() {
System.out.println("第一次使用spring");
}
@Override
public void init() {
System.out.println("初始化方法");
}
@Override
public void destroy() {
System.out.println("销毁方法");
}
}
三、spring配置
1、格式
<bean id=" " class=" " scope="singleton" init-method="init" destroy-method="destroy">
</bean>
2、bean标签作用
定义Java类的,这个类就可以被Spring(new)创建
如果类中没有无参构造函数,则对象创建失败
3、标签属性说明
- id
- 唯一,使用了Schema中唯一的约束,不能出现特殊字符
- Spring整合Struts1的时候name=”/xxxAction”,只能使用name属性
- name
- 不唯一,没有使用Schema中唯一的约束,可以出现特殊字符
- Spring整合struts2的时候,用的是id
- class属性
- class属性用于配置类的全路径,用于工厂类反射生成这个类的实例
- scope属性——对象的作用范围
- singleton:默认,单例模式,配置DAO,Service要是用singleton
- prototype:多例模式。什么时候调用getBean方法,什么时候创建对象,配置Action的时候要使用prototype
- request:应用web开发,创建一个对象,将这个对象存入到request域中
- session:应用web开发,创建一个对象,将这个对象存入到session域中
- globalSession:应用web开发,应用在porlet环境中,没有这个环境的话与session等价的
- init-method——初始化bean
- destroy-method——销毁bean
- 使用前提
- 使用单例模式(scope="singleton")
- 关闭工厂类
- 使用前提
spring工厂
- ApplicationContext接口
- 使用ApplicationContext工厂的接口,使用该接口可以获取到具体的Bean对象
- 该接口下有两个具体的实现类
- ClassPathXmlApplicationContext -- 加载类路径下的Spring配置文件
- FileSystemXmlApplicationContext -- 加载本地磁盘下的Spring配置文件
- BeanFactory工厂(是Spring框架早期的创建Bean对象的工厂接口)
- 使用BeanFactory接口也可以获取到Bean对象
- BeanFactory和ApplicationContext的区别
- BeanFactory:BeanFactory采取延迟加载,第一次getBean时才会初始化Bean
- ApplicationContext:在加载applicationContext.xml时候就会创建具体的Bean对象的实例,还提供了一些其他的功能
- 事件传递
- Bean自动装配
- 各种不同应用层的Context实现
四、实例化bean(创建对象)方式
1、无参构造方法实例化
public class Animal {
public Animal() {
super();
// TODO Auto-generated constructor stub
}
}
<?xml version="1.0" encoding="UTF-8"?>
<!-- spring 约束 -->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 无参数构造方法的实例化 -->
<bean id="animal01" class="com.itheima.domain.Animal"></bean>
</beans>
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.itheima.domain.Animal;
public class TestBean {
@Test
public void test01() throws Exception {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
Animal ani = (Animal) applicationContext.getBean("animal01");
System.out.println(ani);//com.itheima.domain.Animal@d8f459
}
}
2、静态工厂实例化
/**
* @ClassName: AnimalFactory
* @Description:演示静态工厂实例化
* @author jsz
* @date 2018年8月14日
*/
public class AnimalFactory {
public static Animal getAnimal() {
return new Animal();
}
}
<?xml version="1.0" encoding="UTF-8"?>
<!-- spring 约束 -->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 静态工厂实例化 -->
<!-- factory-method :静态方法的名字 -->
<bean id="animal02" class="com.itheima.domain.AnimalFactory"
factory-method="getAnimal">
</bean>
</beans>
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.itheima.domain.Animal;
public class TestBean {
@Test
public void test01() throws Exception {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
Animal ani = (Animal) applicationContext.getBean("animal02");
System.out.println(ani);//com.itheima.domain.Animal@1494678
}
}
3、实例工厂实例化
/**
* @ClassName: AnimalBean
* @Description:演示实例工厂实例化
* @author jsz
* @date 2018年8月14日
*/
public class AnimalBean {
public Animal getAnimal() {
return new Animal();
}
}
<?xml version="1.0" encoding="UTF-8"?>
<!-- spring 约束 -->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 实例工厂实例化的方式 -->
<bean id="factory" class="com.itheima.domain.AnimalBean"></bean>
<bean id="animal03" factory-bean="factory" factory-method="getAnimal"></bean>
</beans>
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.itheima.domain.Animal;
public class TestBean {
@Test
public void test01() throws Exception {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
Animal ani = (Animal) applicationContext.getBean("animal03");
System.out.println(ani);//com.itheima.domain.Animal@d8f459
}
}
五、对象属性注入
1、构造方法注入
1.1 前提条件:
编写Java类,提供有参构造
编写xml文件
1.2 使用的标签:
<constructor-arg>
1.3 标签属性说明:
type:指定的是构造函数中参数的数据类型
index:指定的是构造函数中参数的索引位置(从0开始)
name:指定的是构造函数中参数的名称
value:赋值的数据类型只能是基本类型和String类型
ref:赋值的数据类型是其他bean类型
public class Car {
private String cname;
private double cprice;
public Car(String cname, double cprice) {
super();
this.cname = cname;
this.cprice = cprice;
}
@Override
public String toString() {
return "Car [cname=" + cname + ", cprice=" + cprice + "]";
}
}
public class Person {
private String name;
private Car car;
public Person(String name, Car car) {
super();
this.name = name;
this.car = car;
}
@Override
public String toString() {
return "Person [name=" + name + ", car=" + car + "]";
}
}
<?xml version="1.0" encoding="UTF-8"?>
<!-- spring 约束 -->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 构造方法的注入 -->
<bean id="car" class="com.itheima.domain.Car">
<!-- <constructor-arg name="cname" value="宝马"/> -->
<!-- <constructor-arg name="cprice" value="4500000"/> -->
<constructor-arg index="0" value="香车" />
<constructor-arg index="1" value="500" />
</bean>
<bean id="person" class="com.itheima.domain.Person">
<constructor-arg name="name" value="老新"/>
<!-- 对象类型的属性注入 -->
<constructor-arg name="car" ref="car"/>
</bean>
</beans>
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.itheima.domain.Car;
import com.itheima.domain.Person;
public class TestDI {
/**
* @MethodName:test01
* @Description:构造方法注入
* @throws Exception
*/
@Test
public void test01() throws Exception {
// 创建spring工厂(默认读取src的配置文件)
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext(
"applicationContext.xml");
// 通过工厂获得类
Person persion = (Person) applicationContext.getBean("person");
System.out.println(persion);
}
@Test
public void test02() throws Exception {
}
}
2、set方法属性注入
2.1 前提条件:
在类中提供要注入的对象的set方法
2.2 使用的标签:
<property>
2.3 标签属性:
name:指定的是set方法后面的部分
value:赋值类型是String和基本类型
ref:赋值类型是其他bean类型
public class Car {
private String cname;
private double cprice;
public void setCname(String cname) {
this.cname = cname;
}
public void setCprice(double cprice) {
this.cprice = cprice;
}
@Override
public String toString() {
return "Car [cname=" + cname + ", cprice=" + cprice + "]";
}
}
public class Person {
private String name;
private Car car;
public void setName(String name) {
this.name = name;
}
public void setCar(Car car) {
this.car = car;
}
@Override
public String toString() {
return "Person [name=" + name + ", car=" + car + "]";
}
}
<?xml version="1.0" encoding="UTF-8"?>
<!-- spring 约束 -->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- set方法注入 -->
<bean id="car02" class="com.itheima.domain.Car">
<property name="cname" value="宝马"/>
<property name="cprice" value="4500000"/>
</bean>
<bean id="person02" class="com.itheima.domain.Person">
<property name="name" value="老新"/>
<!-- 对象类型的属性注入 -->
<property name="car" ref="car02"/>
</bean>
</beans>
import static org.junit.Assert.*;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.itheima.domain.Car;
import com.itheima.domain.Person;
public class TestDI {
/**
* @MethodName:test02
* @Description:set方法注入
* @throws Exception
*/
@Test
public void test01() throws Exception {
// 创建spring工厂(默认读取src的配置文件)
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext(
"applicationContext.xml");
// 通过工厂获得类
Person person = (Person) applicationContext.getBean("person02");
System.out.println(person);
}
}
3、p名称空间(spring2.5以后)
3.1 前提条件:
引入P名称空间:xmlns:p="http://www.springframework.org/schema/p"
Java类中提供属性的SET方法
<?xml version="1.0" encoding="UTF-8"?>
<!-- spring 约束 -->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 使用P名称空间属性注入 -->
<!-- 普通类型的属性 p:属性名="" -->
<!-- 对象类型的属性 p:属性名-ref="" -->
<bean id="car01" class="com.itheima.domain.Car" p:cname="宝马"
p:cprice="4500000"></bean>
<bean id="person01" class="com.itheima.domain.Person" p:name="李四"
p:car-ref="car01" />
</beans>
public class Car {
private String cname;
private double cprice;
public void setCname(String cname) {
this.cname = cname;
}
public void setCprice(double cprice) {
this.cprice = cprice;
}
@Override
public String toString() {
return "Car [cname=" + cname + ", cprice=" + cprice + "]";
}
}
public class Person {
private String name;
private Car car;
public void setName(String name) {
this.name = name;
}
public void setCar(Car car) {
this.car = car;
}
@Override
public String toString() {
return "Person [name=" + name + ", car=" + car + "]";
}
}
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.itheima.domain.Person;
public class TestDI {
/**
* @MethodName:test03
* @Description:使用P名称空间属性注入
* @throws Exception
*/
@Test
public void test03() throws Exception {
// 创建spring工厂(默认读取src的配置文件)
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext(
"applicationContext.xml");
// 通过工厂获得类
Person person = (Person) applicationContext.getBean("person01");
System.out.println(person);//Person [name=李四, car=Car [cname=宝马, cprice=4500000.0]]
}
}
SpEL表达式
4、集合类型属性注入
- 数组赋值
<property name="arrs">
<list>
<value>哈哈</value>
<value>呵呵</value>
<value>嘿嘿</value>
</list>
</property>
- list集合赋值
<property name="list">
<list>
<value>a</value>
<value>b</value>
<value>c</value>
</list>
</property>
- set集合赋值
<property name="set">
<set>
<value>1</value>
<value>2</value>
<value>3</value>
</set>
</property>
- map集合赋值
<property name="map">
<map>
<entry key="aaa" value="小王"></entry>
<entry key="bbb" value="小张"></entry>
</map>
</property>
- properties赋值
<property name="pro">
<props>
<prop key="username">tom</prop>
<prop key="password">123</prop>
</props>
</property>
案例
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Properties;
public class User {
private String[] arrs;
public void setArrs(String[] arrs) {
this.arrs = arrs;
}
private List<String> list;
public void setList(List<String> list) {
this.list = list;
}
private HashSet<String> set;
public void setSet(HashSet<String> set) {
this.set = set;
}
private HashMap<String, String> map;
public void setMap(HashMap<String, String> map) {
this.map = map;
}
private Properties pro;
public void setPro(Properties pro) {
this.pro = pro;
}
@Override
public String toString() {
return "User [arrs=" + Arrays.toString(arrs) + ", list=" + list + ", set=" + set + ", map=" + map + ", pro="
+ pro + "]";
}
}
<?xml version="1.0" encoding="UTF-8"?>
<!-- spring 约束 -->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 复杂类型属性注入 -->
<bean id="user" class="com.itheima.domain.User">
<!-- 数组类型的属性注入 -->
<property name="arrs">
<list>
<value>哈哈</value>
<value>呵呵</value>
<value>嘿嘿</value>
</list>
</property>
<!-- List集合类型的属性注入 -->
<property name="list">
<list>
<value>a</value>
<value>b</value>
<value>c</value>
</list>
</property>
<!-- set集合属性注入 -->
<property name="set">
<set>
<value>1</value>
<value>2</value>
<value>3</value>
</set>
</property>
<!-- map集合属性注入 -->
<property name="map">
<map>
<entry key="aaa" value="小王"></entry>
<entry key="bbb" value="小张"></entry>
</map>
</property>
<!-- properties属性注入 -->
<property name="pro">
<props>
<prop key="username">tom</prop>
<prop key="password">123</prop>
</props>
</property>
</bean>
</beans>
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.itheima.domain.User;
public class TestDI {
/**
* @MethodName:test01
* @Description:测试复杂类型注入
* @throws Exception
*/
@Test
public void test01() throws Exception {
// 创建spring工厂(默认读取src的配置文件)
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext(
"applicationContext.xml");
// 通过工厂获得类
User user = (User) applicationContext.getBean("user");
System.out.println(user);
}
}
配置文件的管理
引入其他配置文件
<import resource="bean.xml"/>
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
"applicationContext.xml","applicationContext2.xml");