- 什么是Spring?
- 为什么要使用Spring?
- 快速入门案例
- 怎样理解IoC和DI
1. 什么是Spring?
首先讲一下没有Spring的时期,Java是根据EJB来进行企业级开发。EJB进行开发有两个问题
- 框架上手难度大
- 重量级框架对代码侵入较大
Spring的诞生的初衷就是为了让Java企业级开发框架更加轻松、入侵性更小、更加松耦合
Spring 框架是 现代Java 应用最广的框架,是一种变成思想,它的理念包括 IoC (Inversion of Control,控制反转) 和 AOP(Aspect Oriented Programming,面向切面编程)。
2. 为什么要使用Spring?
Spring本身解决了我们出现的问题
- 低侵入 / 低耦合 (降低组件之间的耦合度,实现软件各层之间的解耦)
- 声明式事务管理(基于切面和惯例)
- 方便集成其他框架(如MyBatis、Hibernate)
- 降低 Java 企业级开发难度
- Spring 框架中包括了 J2EE 三层的每一层的解决方案(一站式)
3 快速上手
实体类
package pojo;
public class User {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void getMessage(){
System.out.println("HellWord " + name);
}
}
applicationContext.xml
SpringTest
package test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import pojo.User;
public class SpringTest {
public static void main(String[] args) {
//创建容器实例
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//将容器赋给Bean对象
User user1 = (User) context.getBean("user");
//打印Bean对象结果
user1.getMessage();
}
}
运行结果
4. 怎样理解IoC和DI?
Q:我觉得用new对象也很方便啊,感觉用Spring以后更加麻烦了?
A:首先一个一个new对象方便仅限于对象不多,直接调用确实更加方便。但是企业级开发业务很复杂对象很多,如果都是用new的话,突然有一个对象关系改变了,其它的地方都要修改。有可能漏掉一个使程序报错
通过一个例子来更清晰的解释
4.1 什么是IoC?
IoC(Inverse of Control:控制反转)是一种设计思想,不是一种新的技术。就是将原本在程序中手动创建对象的控制权,交由Spring框架来管理。
- 正控:我们需要的对象由我们自己手动new出来
- 反控:我们需要什么对象就去从 Spring 容器中获取需要使用的对象,不关心对象的创建过程,也就是把创建对象的控制权反转给了Spring框架,从而进行对象的解耦。
举个例子
- 公司需要开发、测试、产品这些岗位,公司逐一去招人就是正控,需要我们自己一个一个去招到
- 公司需要开发、测试、产品这些岗位,委托第三方猎头公司进行招人,这样就可以根据我的需求来进行招人。这样就是反转控制。
同理还有如果想喝果汁就要从买水果、买榨汁机开始。如果你去果汁店直接就有果汁能喝到一样
4.3 DI依赖注入
Q:既然对象的创建是由Spring容器中创建,那么对象和对象之间的依赖关系是怎样解决的呢?
A:利用DI进行对象间的依赖注入。
IoC的实现方式分为两种
- 依赖查找
- 依赖注入
依赖查找需要使用容器API来进行依赖的资源和协作对象。这种方式虽然降低了对象间的依赖,但是同时也使用到了容器的API,造成了我们无法在容器外使用和测试对象。
IoC 最常见以及最合理的实现方式叫做依赖注入(Dependency Injection,简称 DI)。相对于IoC而言,依赖注入(DI)更加准确地描述了IoC的设计理念。所谓依赖注入,即组件之间的依赖关系由容器在应用系统运行期来决定,也就是由容器动态地将某种依赖关系的目标对象实例注入到应用系统中的各个关联的组件之中。
4.3.1 set注入
UserDao
public interface UserDao {
void addUser();
}
UserDaoImpl
package dao;
public class UserDaoImpl implements UserDao {
public void addUser() {
System.out.println("增加学生");
}
}
UserService
public interface UserService {
void addUser();
}
UserServiceImpl
import dao.UserDao;
import dao.UserDaoImpl;
public class UserServiceImpl implements UserService {
private UserDao userDao;
public void addUser() {
// UserDao userDao = new UserDaoImpl();
// userDao.addUser();
userDao.addUser();
}
public UserDao getUserDao() {
return userDao;
}
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
}
applicationContext.xml
SpringTest
package test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import service.UserService;
public class SpringTest {
public static void main(String[] args) {
// UserService service = new UserServiceImpl();
// service.addUser();
//创建容器实例
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//将容器赋给Bean对象
UserService userService = (UserService) context.getBean("userService");
userService.addUser();
}
}
4.3.2 构造器注入
UserServiceImpl
package test.service;
import test.dao.UserDao;
import org.springframework.stereotype.Service;
@Service("userService")
public class UserServiceImpl implements UserService {
private UserDao userDao;
public void addUser() {
userDao.addUser();
}
public UserServiceImpl(UserDao userDao) {
this.userDao = userDao;
}
}
4.3.3 注解注入 (待补)
package test.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import test.dao.UserDao;
@Service("userService")
public class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao;
public void addUser() {
userDao.addUser();
}
}