目录
2.4 创建对应的包结构,编写Java的类,要注意:以后使用Spring框架做开发,都需要来编写接口与实现类!!
2.5 想把UserServiceImpl实现类的创建交给Spring框架来管理,需要创建Spring框架的配置文件,完成配置
2.5编写测试程序,采用Spring框架的工厂方式来获取到UserService接口的具体实现类!!
3.2 BeanFactory工厂(是Spring框架早期的创建Bean对象的工厂接口)(不推荐)
3.3BeanFactory和ApplicationContext的区别
7.6数组,集合(List,Set,Map),Properties等的注入
步骤三:在src的目录下,创建applicationContext.xml的配置文件
步骤四:在applicationContext.xml配置文件中加入开启组件扫描
10.1Spring中提供@Component的三个衍生注解:(功能目前来讲是一致的)
* @Controller -- 作用在WEB层 * @Service -- 作用在业务层 * @Repository(仓库) -- 作用在持久层
* 说明:这三个注解是为了让标注类本身的用途清晰,Spring在后续版本会对其增强
属性注入的注解(说明:使用注解注入的方式,可以不用提供set方法)
@Resource =@Autowired +@Qualifier
注意:假如在service层注入完后,service层就可以调用dao层的内容的
1.Spring框架的概述
1.1 spring框架的概念
- Spring是一个开源框架
- 2003 年兴起的一个轻量级的Java开发框架
- 为了解决企业应用开发的复杂性而创建,不仅限于服务器端的开发,任何Java应用都可以(简单性、可测试性和松耦合的角度而言)
- 核心是控热制反转(IoC)和面向切面(AOP)
- 简单来说,Spring是一个分层的JavaSE/EEfull-stack(一站式) 轻量级开源框架。为什么说它是一站式呢?
我们来看一下EE开发分成三层结构
WEB层 -- Spring MVC
业务层 -- Bean管理:(IOC)
持久层 -- Spring的JDBC模板.ORM模板用于整合其他的持久层框架
1.2Spring框架的特点
-
方便解耦,简化开发
Spring就是一个大工厂,可以将所有对象创建和依赖关系维护,交给Spring管理
-
AOP编程的支持
Spring提供面向切面编程,可以方便的实现对程序进行权限拦截、运行监控等功能
- 声明式事务的支持
只需要通过配置就可以完成对事务的管理,而无需手动编程
- 方便程序的测试
Spring对Junit4支持,可以通过注解方便的测试Spring程序
- 方便集成各种优秀框架
Spring不排斥各种优秀的开源框架,内部提供了对各种优秀框架(如:Struts2、Hibernate、MyBatis、Quartz等)直接支持.
- 降低JavaEE API的使用难度
Spring 对JavaEE开发中非常难用一些API(JDBC、JavaMail、远程调用等),都提供了封装,使这些API应用难度大大降低
1.3 体系结构图
2.Spring框架的IOC核心功能快速入门
2.1. 什么是IOC的功能?
IoC (Inverse of Control )控制反转,将对象的创建权反转给Spring!!
2.2下载Spring框架的开发包
下载Spring框架的开发包
* 官网:http://spring.io/
* 下载地址:http://repo.springsource.org/libs-release-local/org/springframework/spring解压:(Spring目录结构:)
* docs -- API和开发规范
* libs -- jar包和源码
* schema -- 约束
2.3创建JavaWEB项目,引入Spring的开发包
- 引入Spring框架IOC核心功能需要的具体的jar包
- Spring框架的IOC的功能,那么根据Spring框架的体系结构图能看到,只需要引入如下的jar包(对应体系结构图的最下面)
- Spring框架也需要引入日志相关的jar包
2.4 创建对应的包结构,编写Java的类,要注意:以后使用Spring框架做开发,都需要来编写接口与实现类!!
UserService -- 接口
UserServiceImpl -- 具体的实现类
2.5 想把UserServiceImpl实现类的创建交给Spring框架来管理,需要创建Spring框架的配置文件,完成配置
- 在src目录下创建applicationContext.xml的配置文件,名称是可以任意的,但是一般都会使用默认名称!!
- 引入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">
</beans>
- 完成UserService的配置
<bean id="UserService" class="com.spring.demo1.UserServiceImpl" init-method="init">
2.5编写测试程序,采用Spring框架的工厂方式来获取到UserService接口的具体实现类!!
@Test
public void run1()
{
//创建工厂,获取核心配置文件
ApplicationContext ac =new ClassPathXmlApplicationContext("applicationContext.xml");
//从工厂中获取对象
UserServiceImpl usi=(UserServiceImpl) ac.getBean("UserService");
//上面传入id值,正常返回的是id中多对应的对象(com.spring.demo1.UserServiceImpl)
//调用方法执行
usi.SayHello();
}
3.入门总结之Spring框架中的工厂
3.1 ApplicationContext接口
使用ApplicationContext工厂的接口,使用该接口可以获取到具体的Bean对象
该接口下有两个具体的实现类
- ClassPathXmlApplicationContext 加载类路径下的Spring配置文件
- FileSystemXmlApplicationContext 加载本地磁盘下的Spring配置文件
3.2 BeanFactory工厂(是Spring框架早期的创建Bean对象的工厂接口)(不推荐)
从例子中可以看到他是被拉黑线的
3.3BeanFactory和ApplicationContext的区别
- BeanFactory
BeanFactory采取延迟加载,第一次getBean时才会初始化Bean
- ApplicationContext
在加载applicationContext.xml时候就会创建具体的Bean对象的实例,还提供了一些其他的功能
4.入门总结之配置Spring框架编写XML的提示
1. 步骤一:先复制, http://www.springframework.org/schema/beans/spring-beans.xsd
2. 步骤二:搜索XML Catalog,点击Add按钮
3. 步骤三:先选择Location的schema的约束地址
步骤四:注意:Key type要选择:Schema location
步骤五:Key把http://www.springframework.org/schema/beans/spring-beans.xsd复制上
5.Spring框架中<bean>标签的配置
5.1 id属性和name属性的区别
- id
Bean起个名字,在约束中采用ID的约束,唯一
取值要求:必须以字母开始,可以使用字母、数字、连字符、下划线、句话、冒号 id:不能出现特殊字符
- name
Bean起个名字,没有采用ID的约束(了解)
取值要求:name:出现特殊字符.如果<bean>没有id的话 , name可以当做id使用,但开发一般不用
Spring框架在整合Struts1的框架的时候,Struts1的框架的访问路径是以/开头的,例如:/bookAction
5.2 class属性
Bean对象的全路径 eg:
<bean id="CustomDao" class="com.spring.demo2.CustomerDaoImpl"/>
5.3scope属性
scope属性代表Bean的作用范围
- ①singleton -- 单例(默认值)
- ②prototype -- 多例,在Spring框架整合Struts2框架的时候,Action类也需要交给Spring做管理,配置把Action类配置成多例!!
- ③request -- 应用在Web项目中,每次HTTP请求都会创建一个新的Bean
- ④session -- 应用在Web项目中,同一个HTTP Session 共享一个Bean
- ⑤globalsession -- 应用在Web项目中,多服务器间的session(一个地方登陆成功其他地方就可以用了)
5.4Bean对象的创建和销毁的两个属性配置
Spring初始化bean或销毁bean时,有时需要作一些处理工作,因此spring可以在创建和拆卸bean的时候调用bean的两个生命周期方法
- init-method 当bean被载入到容器的时候调用init-method属性指定的方法
- destroy-method 当bean从容器中删除的时候调用destroy-method属性指定的方法
注:
想查看destroy-method的效果,有如下条件
scope= singleton有效
web容器中会自动调用,但是main函数或测试用例需要手动调用(需要使用ClassPathXmlApplicationContext的close()方法)
6.依赖注入(DI)
6.1IOC和DI的概念
IOC :Inverse of Control,控制反转,将对象的创建权反转给Spring!!
DI : Dependency Injection,依赖注入,在Spring框架负责创建Bean对象时,动态的将依赖对象注入到Bean组件中
6.2 DI(依赖注入)
例如:如果UserServiceImpl的实现类中有一个属性,那么使用Spring框架的IOC功能时,可以通过依赖注入把该属性的值传入进来!!
具体的配置如下
<bean id="us" class="com.itheima.demo1.UserServiceImpl">
<property name="uname" value="小苍老师"/>
</bean>
- 原来的话必须先new好(new UserServiceImpl),然后自己设置name的值setname
- 现在依靠容器中,不用自己管,在注入可以得到:
- 当在获取配置文件中就会创建UserServiceIml这个对象,同时就会把property里面的内容赋值给name
6.3注意:Junit的类起名字不能为Test
假如说这个类名字为Test的话就会报错
7.Spring框架的属性注入(依赖注入的方式)
7.1类成员变量常用的注入方式: 构造函数
-
编写Java的类,提供构造方法
public class Car
{
private String name;
private double money;
public Car(String name, double money) {
this.name = name;
this.money = money;
}
@Override
public String toString() {
return "Car [name=" + name + ", money=" + money + "]";
}
}
- 编写配置文件
<bean id="car" class="com.spring.demo1.Car">
<constructor-arg name="name" value="苍老师"/>
<constructor-arg name="money" value="100"/>
</bean>
<constructor-arg index="0" value="小泽老师"/>
<constructor-arg index="1" value="100"/>
- DemoTest
@Test
public void run1()
{
ApplicationContext ac= new ClassPathXmlApplicationContext("applicationContext.xml");
Car1 c1=(Car1) ac.getBean("car1);
System.out.println(c1);
}
注意:当car这个类创建好之后,交给容器去管理,现在不需要自己去new创建对象了,容器会帮我们创建这个对象,但是这个对象没有空的构造方法,有参数的就一个,所以你在创建对象的时候需要传入两个参数
写配置文件的时候:
- id的值是随便写的,class是全路径
- 注意是两个值需要两个constructor-arg
7.2类成员变量常用的注入方式: setter方法
- 编写Java的类,提供属性和对应的set方法即可
package com.spring.demo2;
public class Car2 {
private String cname;
private Double price;
public String getCname() {
return cname;
}
public void setCname(String cname) {
this.cname = cname;
}
public Double getPrice() {
return price;
}
public void setPrice(Double price) {
this.price = price;
}
@Override
public String toString() {
return "Car2 [cname=" + cname + ", price=" + price + "]";
}
}
- 编写配置文件
<bean id="car2" class="com.spring.demo2.Car2">
<property name="cname" value="范老师"/>
<property name="price" value="1000"/>
</bean>
- DemoTest
@Test
public void run2()
{
ApplicationContext ac= new ClassPathXmlApplicationContext("applicationContext.xml");
Car2 c2=(Car2) ac.getBean("car2);
System.out.println(c1);
}
7.3类成员变量常用的注入方式(属性是另一个Java的类)
value替换成ref(注意这用的是构造方法)
package com.spring.demo3;
public class Person {
private String pname;
private Car1 car1;
public Person(String pname, Car1 car1) {
this.pname = pname;
this.car1 = car1;
}
@Override
public String toString() {
return "Person [pname=" + pname + ", car1=" + car1 + "]";
}
}
<bean id="car2" class="com.spring.demo3.Car2">
</bean>
7.4p名称空间的注入(了解)
- 需要先引入 p 名称空间
配置文件中加入:xmlns:p="http://www.springframework.org/schema/p"
- 使用p名称空间的语法
p:属性名 = ""
p:属性名-ref = ""
- DemoTest
<bean id="person" class="com.spring.demo4.Person" p:pname="老王" p:car2-ref="car2"/>
7.5 SpEL注入方式(了解)
- SpEL:Spring Expression Language是Spring的表达式语言,有一些自己的语法
- 语法 :#{SpEL} 数字直接写 字符串的话加单引号
- 例如如下的代码
<!-- SpEL的方式 -->
<bean id="car2" class="com.spring.demo5.Car2">
<property name="cname" value="#{'马云'}"/>
<property name="price" value="20000"/>
</bean>
- SpEL还支持调用类中的属性或者方法
public class CarInfo
{
public String getCarname(){
return "奔驰";
}
}
value="#{CarInfo.getname}“
7.6数组,集合(List,Set,Map),Properties等的注入
package com.spring.demo4;
import java.util.Arrays;
import java.util.Map;
public class User {
private String [] arr;
public void setArr(String[] arr) {
this.arr = arr;
}
private Map<String,String> map;
public void setMap(Map<String, String> map) {
this.map = map;
}
@Override
public String toString() {
return "User [arr=" + Arrays.toString(arr) + ", map=" + map + "]";
}
}
- 如果是数组或者List集合,注入配置文件的方式是一样的
<bean id="collectionBean" class="com.itheima.demo5.CollectionBean">
<property name="arrs">
<list>
<value>凤姐</value>
<value>小三</value>
</list>
</property>
</bean>
- 如果是Set集合,注入的配置文件方式如下:
<property name="sets">
<set>
<value>哈哈</value>
<value>呵呵</value>
</set>
</property>
- 如果是Map集合,注入的配置方式如下:
<property name="map">
<map>
<entry key="老王2" value="38"/>
<entry key="凤姐" value="38"/>
<entry key="如花" value="29"/>
</map>
</property>
- 如果是properties属性文件的方式,注入的配置如下:
<property name="pro">
<props>
<prop key="uname">root</prop>
<prop key="pass">123</prop>
</props>
</property>
- eg:DemoTest
public void run3()
{
ApplicationContext ac= new ClassPathXmlApplicationContext("applicationContext.xml");
User user=(User)ac.getBean("ColloectionMap");
System.out.println(user);
}
8.Spring框架的配置文件分开管理
- 在src的目录下又多创建了一个配置文件,现在是两个核心的配置文件,那么加载这两个配置文件的方式有两种
主配置文件中包含其他的配置文件(applicationContext2):
<import resource="applicationContext2.xml"/>
DemoTest中工厂创建的时候直接加载多个配置文件:ApplicationContext applicationContext = new ClassPathXmlApplicationContext( "applicationContext.xml","applicationContext2.xml");
9.Spring框架的IOC之注解方式的快速入门
注意:
* (Component)组件注解,标记类
* <bean id="userService" class="com.java.spring.UserServiceImpl">
* 等价于 @Component(value="userService")
* 有了注解全路径就可以省略了,
*但是id不可以,否则类的名称就会默认以小写开头
* 注解都有属性:eg;value
* 是给注解起名字
9.1注解方式的过程:
* 注解的方式
* 开启了注解的扫描,扫描到对应的注解,这个类就会被创建实例对象
* 拿到工厂
*通过id值找到对象然后用它并且调用里面的方法
9.2 注解方式的实现:
-
步骤一:导入注解开发所有需要的jar包
-
步骤二:创建对应的包结构,编写Java的类
* UserService -- 接口
* UserServiceImpl -- 具体的实现类
public interface UserService {
public void save();
public void save1();
}
package com.java.spring_ioc;
public class UserServiceImpl implements UserService {
public void save() {
System.out.println("我是service持久层 你好 :");
}
public void save1()
{
System.out.println("我是service持久层 11你好 :");
}
}
-
步骤三:在src的目录下,创建applicationContext.xml的配置文件
注意:因为现在想使用注解的方式,那么引入的约束发生了变化
需要引入context的约束,具体的约束如下
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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 definitions here -->
</beans>
-
步骤四:在applicationContext.xml配置文件中加入开启组件扫描
<context:component-scan base-package="com.spring.demo1"/>
* 注意:也可以采用如下配置
<context:component-scan base-package="com.spring"/> 这样是扫描com.spring包下所有的内容
-
步骤五:在UserServiceImpl的实现类上添加注解
@Component(value="userService")
相当于在XML的配置方式中 <bean id="userService" class="...">
-
步骤六:编写测试代码
public class SpringDemo1 {
@Test
public void run1(){
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService us = (UserService) ac.getBean("userService");
us.save();
}
}
10.Spring框架中Bean管理的常用注解
10.1Spring中提供@Component的三个衍生注解:(功能目前来讲是一致的)
* @Controller -- 作用在WEB层
* @Service -- 作用在业务层
* @Repository(仓库) -- 作用在持久层
* 说明:这三个注解是为了让标注类本身的用途清晰,Spring在后续版本会对其增强
10.2注入的过程分析
* 在userdao中做一个简单的注入 传统方式是自己new,现在交给容器去管理
* 就在userdaoImpl中加 Component(value=userDao)可以,但是为更还就用 @Repository
* 现在就UserDaoImpl就交给IOC容器去管理了,名字为userDao
* Dao会被扫描到,就去service中注入dao
* 注入就得提供成员属性,private UserDao userDao;
* 但不用提供set方法了,使用注解就不用提供set方法
* 使用@Autowired +@Qualifier
*@Autowired就会去容器中找,扎到UserDao就会自动注入
10.3注入的属性的类型
属性注入的注解(说明:使用注解注入的方式,可以不用提供set方法)
-
如果是注入的普通类型,可以使用value注解
@Value(value="波姐")
private String name;
-
如果注入的是对象类型,使用如下注解
@Autowired
默认按类型进行自动装配
如果想按名称注入
@Qualifier -- 强制使用名称注入
@Autowired//,,注入的是对象类型,使用注解@Autowired他是按类型自动装配
@Qualifier(value="userDao") // 按名称注入
private UserDao userDao;
-
@Resource =@Autowired +@Qualifier
@Resource(name="userDao")
private UserDao userDao;
* 强调:Java提供的注解
* 属性使用name属性
注意:假如在service层注入完后,service层就可以调用dao层的内容的
比如说:在service层就可调用dao层的save方法
eg:
public interface UserDao {
public void saveCustomer();
}
import org.springframework.stereotype.Repository;
@Repository(value="userDao")
public class UserDaoImpl implements UserDao {
@Override
public void saveCustomer() {
System.out.println("保存客户");
}
}
public interface UserService {
public void save();
public void save1();
}
package com.java.spring_ioc;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
//import javax.annotation.Resource;
@Component(value="userService")
public class UserServiceImpl implements UserService {
// 给name属性注入简琦的字符串,setName方法还可以省略不写
@Value(value="简琦")
private String name;
/*
* public void setName(String name) { this.name = name; }
*/
@Autowired//,,注入的是对象类型,使用注解@Autowired他是按类型自动装配
@Qualifier(value="userDao") // 按名称注入
//@Resource(name="userDao")
private UserDao userDao;
public void save() {
System.out.println("我是service持久层 你好 :");
userDao.saveCustomer();
}
public void save1()
{
System.out.println("我是service持久层 11你好 :");
}
}
package com.java.spring_ioc;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class DemoTest {
@Test //传统的方式必须得自己new
public void run1()
{
UserServiceImpl us =new UserServiceImpl();
us.save1();
System.out.println("执行完毕");
}
/**
* 注解的方式
* 开启了注解的扫描,扫描到对应的注解,这个类就会被创建实例对象
* 拿到工厂
*通过id值找到对象然后用它并且调用里面的方法
*/
@Test public void run2() { // 获取工厂,加载配置文件
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService us = (UserService) ac.getBean("userService");
us.save();
}
}
11.Bean的作用范围和生命周期的注解
1. Bean的作用范围注解
* 注解为@Scope(value="prototype"),作用在类上。值如下:
* singleton -- 单例,默认值
* prototype -- 多例
2. Bean的生命周期的配置(了解)
* 注解如下:
* @PostConstruct -- 相当于init-method
* @PreDestroy -- 相当于destroy-method
12.Spring框架整合JUnit单元测试
**不在需要ApplicationContext 每次都new一个ClasspathApplicationtext从配置文件中读取内容的话形式
**可以用注解的方式代替
具体步骤:
要求:必须先有JUnit的环境(即已经导入了JUnit4的开发环境)
- 步骤一:在程序中引入:spring-test.jar
- 步骤二:在具体的测试类上添加注解
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class SpringDemo1 {
@Resource(name="userService")
private UserService userService;
@Test
public void demo2(){
userService.save();
}
}