Spring IOC的介绍
随着java的发展,框架技术开始应用于我们的开发过程,使用框架大大的减少了我们的工作量,框架是经过大佬们对相应的技术进行封装组合最后形成一个框架,并不断地更新和修改他的BUG,今天介绍的是我最近学习的Spring IOC (控制反转)
一、什么是IOC
IOC上文说到是控制反转,控制反转不是一个技术,而是一种思想,之前没学spring IOC 时,我们要使用对象时必须要new出来,现在使用spring IOC后对象的控制我们交给了容器控制,就是我们要使用对象的时候就可以在容器中拿出来用。
- 核心容器:Spring-beans 和 Spring-core 模块是 Spring 框架的核心模块,包含控制反转
(Inversion of Control, IoC)和依赖注入(Dependency Injection, DI),核心容器提供 Spring 框
架的基本功能。核心容器的主要组件是 BeanFactory,工厂模式的实现。BeanFactory 使用控制反
转(IOC) 思想将应用程序的配置和依赖性规范与实际的应用程序代码分开。
Spring 上下文Spring Context:Spring 上下文是一个配置文件,向 Spring 框架提供上下文信息。
Spring 上下文包括企业服务,例如 JNDI、EJB、电子邮件、国际化、校验和调度功能。
Spring-Expression 模块是统一表达式语言(unified EL)的扩展模块,可以查询、管理运行中的对
象,同时也方便的可以调用对象方法、操作数组、集合等。它的语法类似于传统EL,但提供了额外
的功能,最出色的要数函数调用和简单字符串的模板函数。
二、Spring IOC的使用
2.1、创建Spring 项目
2.1.1、环境要求
JDK 版本:
JDK 1.7 及以上版本,推荐使用11,随着JDK的不断更新,现在使用JDK11开发已是主流
Spring版本:
Spring 5.x版本
2.1.2、创建maven项目
- 创建maven的java项目
2.设置项目的坐标、名称、工作空间
2.1.3、导入spring 依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.16.RELEASE</version>
</dependency>
2.1.4、添加spring的配置文件
- 在项目的src下创建文件夹 resources
- 将 resources 标记为资源目录
- 在 src\main\resources 目录下新建 spring.xml 文件,并拷贝官网文档提供的模板内容到 xml 中。
- 配置 bean 到 xml 中,把对应 bean 纳入到 Spring 容器来管理
spring.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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!--开启自动化装配(注入)-->
<context:annotation-config/>
<!-- 设置自动化扫描的范围 -->
<context:component-scan base-package="com.liufeng"/>
</beans>
- 在 spring.xml 中配置 Bean 对象
<!--
id:bean对象的id,唯一标识。一般是Bean对象的名称的首字母小写
class:bean对象的类路径
-->
<bean id="userService" class="com.xxxx.service.UserService"></bean>
2.2、加载配置文件,获取实例化对象
package com.liufeng;
import com.liufeng.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class App {
public static void main(String[] args) {
// 获取Spring上下文环境 (加载配置文件)
ApplicationContext ac = new
ClassPathXmlApplicationContext("spring.xml");
// 通过getBean方法得到Spring容器中实例化好的Bean对象 (实例化Bean对象)
// userService代表的是配置文件中bean标签的id属性值
UserService userService = (UserService) ac.getBean("userService");
// 调用方法 (使用实例化对象)
userService.test();
}
}
三、spring 模拟用户登录过程
接下来通过登录案例直观的给大家介绍spring ioc 的使用
3.1、 Dao层 (查询用户记录)
- 定义JavaBean User.java
package com.liufeng.po;
/**
* 用户实体类:
* 提供get和set方法
*
*/
public class User {
private String userName; // 用户名称
private String userPwd; // 用户密码
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getUserPwd() {
return userPwd;
}
public void setUserPwd(String userPwd) {
this.userPwd = userPwd;
}
}
2.编写Dao层 UserDao.java
package com.liufeng.dao;
import com.liufeng.bean.User;
public class UserDao {
private final String USERNAME="admin";
private final String USERPWD="admin";
/**
*
* 判断username是不是相等
* @param userName
* @return
*/
public User queryUserByUserName(String userName){
User user=null;
// 判断用户名称是否正确
if(!USERNAME.equals(userName)){
// 如果不正确,返回null
return null;
}
user=new User();
// 如果正确,将用户名称和密码设置到user对象中
user.setUsername(USERNAME);
user.setUserpwd(USERPWD);
return user;
}
}
3.2、service 业务层
- 定义业务处理返回消息模型 MessageModel.java
package com.liufeng.modle;
/**
* 定义业务结果,返回业务结构
* 提供get,set方法
*/
public class MessageModel {
private Integer resultcode=1;
private String resultmsg="操作成功";
public Integer getResultcode() {
return resultcode;
}
public void setResultcode(Integer resultcode) {
this.resultcode = resultcode;
}
public String getResultmsg() {
return resultmsg;
}
public void setResultmsg(String resultmsg) {
this.resultmsg = resultmsg;
}
}
- 编写Service层 UserService.java
package com.liufeng.service;
import com.liufeng.bean.User;
import com.liufeng.dao.UserDao;
import com.liufeng.modle.MessageModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service(开启扫描器)
public class UserService {
@Autowired(自动装配)
private UserDao userdao;
public MessageModel userLoginCheck(String username,String userpwd){
MessageModel messageModel = new MessageModel();
//判断用户名称是否非空
if(null==username||"".equals(username.trim())){
messageModel.setResultcode(0);
messageModel.setResultmsg("用户名不为空");
return messageModel;
}
// 判断用户密码是否为空
if (null==userpwd||"".equals(userpwd.trim())){
messageModel.setResultcode(0);
messageModel.setResultmsg("密码不能为空");
return messageModel;
}
// 通过用户名称查询用户对象
User user = userdao.queryUserByUserName(username);
// 判断用户对象是否为空
if (null==user){
messageModel.setResultcode(0);
messageModel.setResultmsg("用户不存在");
return messageModel;
}
//用户名正确判断密码
if(!user.getUserpwd().equals(userpwd)){
messageModel.setResultcode(0);
messageModel.setResultmsg("密码不正确");
return messageModel;
}
messageModel.setResultmsg("登录成功");
return messageModel;
}
}
3.3、Controller层 (接收请求)
- 编写Controller层 UserController.java
package com.liufeng.controller;
import com.liufeng.po.vo.MessageModel;
import com.liufeng.service.UserService1;
import org.springframework.stereotype.Controller;
import javax.annotation.Resource;
@Controller
public class UserController {
@Resource
private UserService userService;
/**
* 用户登录
* @param userName
* @param userPwd
* @return
7.2.4. 通过 JUnit 进行测试
8. Bean的作用域与生命周期
8.1. Bean的作用域
默认情况下,我们从Spring容器中拿到的对象均是单例的,对于bean的作用域类型如下:
8.1.1. singleton 作用域
*/
public MessageModel login(String userName, String userPwd){
// 调用Dao层判断用户登录操作,返回结果
MessageModel messageModel = userService.userLoginCheck(userName,
userPwd);
return messageModel;
}
}
3.4、通过 JUnit 进行测试
package com.liufeng;
import com.liufeng.controller.UserController;
import com.liufeng.po.vo.MessageModel;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestLogin {
@Test
public void test() {
// 得到Spring容器上下文环境
ApplicationContext ac = new
ClassPathXmlApplicationContext("spring.xml");
// 得到UserController实例化对象
UserController userController = (UserController)
ac.getBean("userController");
// 传入参数调用UserController的方法,返回封装类
MessageModel messageModel= userController.login("admin", "admin");
System.out.println("状态码:" + messageModel.getResultCode() + ",提示信
息:" + messageModel.getResultMsg());
}
}
四、注解的意思
- @Repository (Dao层)
@Repository
public class ResourceDao {
public void test() {
System.out.println("ResourceDao...");
}
}
2.@Service(Service层 )
@Service
public class ResourceService {
@Resource
private ResourceDao resourceDao; // service层注入dao层的bean对象
public void test() {
System.out.println("ResourceService...");
resourceDao.test();
}
}
3.@Controller (Controller 层 )
@Controller
public class ResourceController {
@Autowired
private ResourceService resourceService; // Controller层注入service层的
bean对象
public void test() {
System.out.println("ResourceController...");
resourceService.test();
}
}
4.@Component (任意层)
@Component
public class PropertyUtils {
public void test(){
System.out.println("PropertyUtils...");
}
}
ic class ResourceController {
@Autowired
private ResourceService resourceService; // Controller层注入service层的
bean对象
public void test() {
System.out.println(“ResourceController…”);
resourceService.test();
}
}
4.@Component (任意层)
```java
@Component
public class PropertyUtils {
public void test(){
System.out.println("PropertyUtils...");
}
}