1、相关概念
1.1、Spring来源
官网:Spring | Home
Spring是一个分层的Java SE/EE应用一站式的轻量级开源框架。Spring核心是IOC
和AOP
。
Spring主要优点包括:
- 方便解耦,简化开发,通过Spring提供的IoC容器,我们可以将对象之间的依赖关系交由Spring进行控制,避免硬编码造成的程序耦合度高。
- AOP编程的支持,通过Spring提供的AOP功能,方便进行面向切面编程。
- 声明式事务的支持,在Spring中,我们可以从单调烦闷的事务管理代码中解脱出来,通过声明式方式灵活地进行事务的管理,提高开发效率和质量。
- 方便程序的测试,可以用非容器依赖的编程方式进行几乎所有的测试工作。
- 方便集成各种优秀框架,Spring提供了对各种优秀框架的直接支持
2002年,Rod Jahnson首次推出了Spring框架雏形interface21框架。
2004年3月24日,Spring框架以interface21框架为基础,经过重新设计,发布了1.0正式版。
Spring是一个轻量级的控制反转(IOC)和面向切面(AOP)的容器(框架)。
1.2、Spring系统架构
Spring 框架是一个分层架构,由 7 个定义良好的模块组成。Spring 模块构建在核心容器之上,核心容器定义了创建、配置和管理 bean 的方式 .
DI:依赖注入,一个BookService类的功能需要依赖另外一个BookDao类配合,同时需要附上一个具体的对象,则成这种关系是依赖注入;IOC:控制反转,以前依赖的对象自己直接new,现在不需要new,框架会自动注入对象,创建对象的权利转移给了框架;
Spring框架负责所有对象的创建、管理和依赖注入;所有的对象存储的容器叫做IOC容器;
dao包
1.接口BookDao
public interface BookDao {
public void insert();
}
2.实现类BookDaoImpl
public class BookDaoImpl implements BookDao {
@Override
public void insert() {
System.out.println("BookDaoImpl......insert");
}
}
service包
1.接口BookService
public interface BookService {
void save();
}
2.实现类BookServiceImpl
public class BookServiceImpl implements BookService {
private String name;
private BookDao bookDao;
public void setName(String name) {
this.name = name;
}
public void setBookDao(BookDao bookDao) {
this.bookDao = bookDao;
}
@Override
public void save() {
System.out.println("BookServiceImpl......save+name");
bookDao.insert();
}
}
BookServiceImpl需要给bookDao属性设置setter方法,框架才能自动注入
servlet包
在servlet中进行测试
1.首先获取IOC的容器;
2.从容器中获取bookService对象;
3.执行方法:servlet执行---service执行,由于spring完成了依赖注入------dao包执行
public class BookServlet {
BookService bookService;
@Test
public void add() {
System.out.println("BookServlet...add");
//1.获得IOC容器
ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("spring.xml");
//2.根据名字从容器中获取对象
bookService= (BookService) context.getBean("bookService");
bookService.save();
}
}
3.2、创建spring的核心配置文件
bean标签:把对应class的对象创建到IOC容器中,如果当前对象有依赖的其他对象,那么可以通过property对依赖的对象使用ref引用容器中已经注册过的对象。
把所有对象创建到spring的IOC容器中,并起上名字;id:表示给对象起名字 class:类的全类名spring的依赖注入:property表示BookServiceImpl的属性,常规属性使用value赋值,类型属性使用ref引用
<?xml version="1.0" encoding="UTF-8"?>
<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="bookDao" class="com.zhan.dao.impl.BookDaoImpl"></bean>
<bean id="bookService" class="com.zhan.service.impl.BookServiceImpl">
<property name="name" value="张三"/>
<property name="bookDao" ref="bookDao"/>
</bean>
</beans>
控制台日志信息
4.bean作用范围scope配置
singleton:单列,框架会唯一创建该对象,后续获取的都是同一个,在配置文件加载的时候创建了
prototype:非单例/多例,框架在每次获取的时候创建一个新的,在获得的时候创建。多线程
单例
<bean id="bookService" class="com.zhan.service.impl.BookServiceImpl" scope="singleton">
<property name="bookDao" ref="bookDao"/>
</bean>
多例
<bean id="bookService" class="com.zhan.service.impl.BookServiceImpl" scope="prototype">
<property name="bookDao" ref="bookDao"/>
</bean>
5.静态工厂实例化
factory:工厂对象;工厂类就是制造对象的,一般没有功能;
class:工厂类的全类名
factory-method:具体工厂类中创建对象的方法名
配置
<bean id="bookService3" class="com.zhan.factory.BookServiceFactory"></bean>
测试
public class Test02 {
@Test
public void test02(){
ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("spring.xml");
BookServiceFactory factory = (BookServiceFactory) context.getBean("bookService3");
System.out.println(factory);
}
}
日志信息
配置工厂
<!--配置工厂,但是获得的工厂的商品 -->
<bean id="bookService3" class="com.zhan.factory.BookServiceFactory" factory-method="getBean"></bean>
静态工厂创建对象
public class BookServiceFactory {
public static BookService getBean(){
return new BookServiceImpl();
}
}
测试类
public class Test02 {
@Test
public void test02(){
ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("spring.xml");
BookService factory = (BookService) context.getBean("bookService3");
System.out.println(factory);
}
}
日志信息
6.setter注入
配置中使用property标签的ref属性注入引用类型对象
对于基本数据类型(包括String),指定属性值使用"value"属性,而对于引用类型使用"ref"属性。
<bean id="bookService" class="com.zhan.service.impl.BookServiceImpl" scope="singleton">
<property name="bookDao" ref="bookDao"/>
</bean>
在BookServiceImpl中定义引用类型属性,提供可访问的setter方法
public class BookServiceImpl implements BookService {
BookDao bookDao;
public void setBookDao(BookDao bookDao) {
this.bookDao = bookDao;
}
}
7.构造器注入
使用constructor-arg标签进行依赖注入,name属性要与实现类中提供的形参类型和个数一致,否则将会报错。
<bean id="bookService1" class="com.zhan.service.impl.BookServiceImpl" scope="singleton">
<constructor-arg name="name" value="张三"/>
<constructor-arg name="bookDao" ref="bookDao"/>
</bean>
在BookServiceImpl中定义引用类型属性,提供有参的构造方法
public class BookServiceImpl implements BookService {
String name;
BookDao bookDao;
public BookServiceImpl(String name, BookDao bookDao) {
System.out.println("有参");
this.name = name;
this.bookDao = bookDao;
}
}
8.集合注入
使用相应标签(list、set、array、map...)对属性值进行注入
<bean id="bookService2" class="com.zhan.service.impl.BookServiceVip">
<property name="list">
<list>
<value>张三</value>
<value>张四</value>
<value>张五</value>
</list>
</property>
<property name="set">
<set>
<value>南阳</value>
<value>信阳</value>
<value>濮阳</value>
<value>安阳</value>
<value>开封</value>
<value>郑州</value>
</set>
</property>
<property name="map">
<map>
<entry key="name" value="张三"/>
<entry key="age" value="20"/>
<entry key="sex" value="男"/>
</map>
</property>
</bean>
在BookServiceVipl中定义引用类型属性,提供可访问的setter方法
public class BookServiceVip implements BookService {
List<String> list;
Set<String> set;
Map<String,String> map;
public void setList(List<String> list) {
this.list = list;
}
public void setSet(Set<String> set) {
this.set = set;
}
public void setMap(Map<String, String> map) {
this.map = map;
}
@Override
public String toString() {
return "BookServiceVip{" +
"list=" + list +
", set=" + set +
", map=" + map +
'}';
}
}
9.注解
1.创建项目导入jar包
2.创建接口和实体类
配置文件
<?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: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">
<!--让系统去扫描注解-->
<context:component-scan base-package="com.zhan"/>
</beans>
自动注入
优先按照类型注入,如果有多个对象,按照名字进行注入
@Override注解告诉你下面这个方法是从父类/接口继承过来的,需要你重写一次,这样就可以方便你阅读,也不怕会忘记。是伪代码,表示重写(当然不写也可以);
@Componet:自动扫描
@Autowired:自动注入属性
@Qualifier:指定名字进行注入
BookDaoImpl类使用注解 @Componet
@Component("bookDao")
public class BookDaoImpl implements BookDao {
@Override
public void insert() {
System.out.println("BookDaoImpl......insert");
}
}
BookServiceImpl类使用注解 @Componet ;@Autowired
@Component("bookService")
public class BookServiceImpl implements BookService {
//自动注入优先按照类型注入,如果有多个对象,按照名字进行注入
@Autowired
BookDao bookDao;
public void setBookDao(BookDao bookDao) {
this.bookDao = bookDao;
}
@Override
public void save() {
System.out.println("BookServiceImpl......save");
bookDao.insert();
}
}
测试类
public class Test01 {
BookService bookService;
@Test
public void test01(){
ClassPathXmlApplicationContext context =new ClassPathXmlApplicationContext("spring.xml");
//按照类型获得对象,前提类型有唯一的对象
bookService = context.getBean(BookService.class);
this.bookService.save();
}
}
打印日志