spring IOC

spring IOC

spring是java的众多开源项目的中的一员,主要核⼼是IOC(控制反转/依赖注⼊)与 AOP(⾯向切⾯) 两⼤技术,实现项目开发过程的解耦,提高项目的开发效率。

首先我们先来学习下IOC的知识。

环境配置

1>创建一个maven的项目,目前因为我们还不用与网页的交互,可以先创建一个quickstart的项目.

2>项目环境的修改(pom.xml中)

jdk版本的修改;JUnit 版本的修改(可以改为4.12);删除build标签中的pluginManagement标签

3>添加依赖(pom.xml中的< dependencies>标签中添加)

​ 添加Spring框架的核⼼依赖(spring-context)

​ 其他的spring依赖之后用到时,再添加

4>创建完善目录文件

​ 一般我们的目录:

main–java–package(com.xxx)—包controller|dao|service|po–类UserController|UserDao|UserService|User

和java的同一级目录下新建resources文件(标记为Resources Root)—spring.xml

在这里插入图片描述

dao层:数据访问层,操作数据库相关的操作

Service层叫服务层,被称为服务,对一个或多个DAO进行的再次封装,封装成一个服务

Controler负责请求转发,接受页面过来的参数,传给Service处理,接到返回值,再传给页面。

5>编写 Bean 对象

下面代码中是写在UserService中的,写在其他类中也是可以运行的

package com.xxxx.service;

public class UserService {
	public void test(){
		System.out.println("Hello Spring!");
	}
}

6>配置spring.xml

spring.xml的配置:我们可以到官网上复制,之后配置bean到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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">

 <!--
id:bean对象的id,唯⼀标识。⼀般是Bean对象的名称的⾸字⺟⼩写
class:bean对象的类路径
-->    

    <bean id="userSer" class="com.xxxx.service.UserSer"></bean>
</beans>    

7>加载配置文件,实例化对象

可以直接在自动生成的App类中写

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();
    }
}

实例化bean对象

实例化bean有构造器|静态工厂|实例化工厂 实例化;这边主要讲下构造器实例化.

开发中项⽬⼀般使⽤ 构造器实例化 ⽅式实例化bean,项⽬开发基本采⽤构造器⽅式,交给Spring托管,使⽤时直接拿来使⽤即可。

构造器实例化

通过默认构造器创建 空构造⽅法必须存在 否则创建失败

和前边我们在环境配置中的应用是差不多的.

1>设置配置⽂件 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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="userService" class="com.xxxx.service.UserService"></bean>
</beans>

2>获取实例化对象

ApplicationContext ac = new ClassPathXmlApplicationContext("spring.xml");
UserService userService = (UserService) ac.getBean("userService");
userService.test();

三种实例化的区别

构造器:通过bean的缺省构造函数创建,当各个bean的业务逻辑相互⽐较独⽴的时候或者和外界
关联较少的时候可以使⽤。
静态工厂:利⽤静态factory⽅法创建,可以统⼀管理各个bean的创建,如各个bean在创建之前需要
相同的初始化处理,则可⽤这个factory⽅法险进⾏统⼀的处理等等。
实例化工厂:利⽤实例化factory⽅法创建,即将factory⽅法也作为了业务bean来控制,1可⽤于集成
其他框架的bean创建管理⽅法,2能够使bean和factory的⻆⾊互换。

依赖注入

手动注入

Spring ⽀持的注⼊⽅式共有四种:set 注⼊、构造器注⼊、静态⼯⼚注⼊、实例化⼯⼚注⼊。同样这边只介绍下set和构造器注入.另外两种在项目中也使用的不多,这边就不介绍了.

set注入

前提:属性字段需要提供set⽅法

这里需要将dao层的注入的service层,因此需要先写下dao层

package com.xxxx.dao;

public class UserDao {

    public void test(){
        System.out.println("连接数据库,查询数据");
    }
}

1>属性字段提供set方法

public class UserService {
	// 业务对象UserDao set注⼊(提供set⽅法)
	private UserDao userDao;
	public void setUserDao(UserDao userDao) {
		this.userDao = userDao;
	}
}

2>配置⽂件的bean标签设置property标签

<!--
IOC通过property标签⼿动装配(注⼊):
Set⽅法注⼊
name:bean对象中属性字段的名称
ref:指定bean标签的id属性值 | value:具体的值(基本类型 常⽤对象|⽇期 集合)
-->
<bean id="userDao" class="com.xxxx.dao.UserDao"></bean>
<bean id="userService" class="com.xxxx.service.UserService">
	<!--业务对象 注⼊-->
	<property name="userDao" ref="userDao"/>
</bean>

spring2.5以后,为了简化setter⽅法属性注⼊,引⽤p名称空间的概念,可以将 ⼦元素,简化为元素
属性配置。

构造器注入

提供带参构造器

java代码和xml配置

public class UserService {
	private UserDao userDao; // JavaBean 对象
	public UserService(UserDao userDao) {
		this.userDao = userDao;
	}
	public void test(){
		System.out.println("UserService Test...");
	}

<bean id="userDao" class="com.xxxx.dao.UserDao" ></bean>
<bean id="userService" class="com.xxxx.service.UserService">
	<constructor-arg name="userDao" ref="userDao"></constructor-arg>
</bean>

循环问题产⽣的原因:
Bean通过构造器注⼊,之间彼此相互依赖对⽅导致bean⽆法实例化。

解决:将构造器注⼊改为set⽅法注⼊

自动注入

准备环境

<!--开启⾃动化装配(注⼊)-->
<context:annotation-config/>

<bean id="userDao" class="com.xxxx.dao.UserDao"></bean>
<bean id="userService" class="com.xxxx.service.UserService"></bean>
@Resource注解

@Resource注解实现⾃动注⼊(反射)
如果报错,可以试下导入javax.annotation-api依赖

  • 默认根据属性字段名称查找对应的bean对象
  • 如果属性字段名称未找到,则会通过类型(Class类型)查找
  • 属性可以提供set⽅法,也可以不提供set⽅法
  • 注解可以声明在属性级别 或 set⽅法级别
  • 可以设置name属性,name属性值必须与bean标签的id属性值⼀致;如果设置了name属性值, 就只会按照name属性值查找bean对象
  • 当注⼊接⼝时,如果接⼝只有⼀个实现则正常实例化;如果接⼝存在多个实现,则需要使⽤name 属性指定需要被实例化的bean对象
public class UserService {
	@Resource //@Resource(name = "userDao")
	private UserDao userDao; // 属性字段的名称与bean标签的id属性值相等
	public void setUserDao(UserDao userDao) {
		this.userDao = userDao;
	}
	public void test() {
		// 调⽤UserDao的⽅法
		userDao.test();
}	
@Autowired注解

@Autowired注解实现⾃动化注⼊:

  • 默认通过类型(Class类型)查找bean对象 与属性字段的名称⽆关
  • 属性可以提供set⽅法,也可以不提供set⽅法
  • 注解可以声明在属性级别 或 set⽅法级别
  • 可以添加@Qualifier结合使⽤,通过value属性值查找bean对象(value属性值必须要设置,且值 要与bean标签的id属性值对应)
public class UserService {
	@Autowired
    // value属性值必须要设置,且值要与bean标签的id属性值对应
    //@Qualifier(value="userDao") 
	private UserDao userDao; // 默认通过类型(Class类型)查找bean对象 与属性字段的名称⽆关
	public void setUserDao(UserDao userDao) {
		this.userDao = userDao;
	}
	public void test() {
		// 调⽤UserDao的⽅法
		userDao.test();
	}
}

扫描器

实际的开发中,bean的数量⾮常多,采⽤⼿动配置bean的⽅式已⽆法满⾜⽣产需要,Spring这时候
同样提供了扫描的⽅式,对扫描到的bean对象统⼀进⾏管理,简化开发配置,提⾼开发效率。

Spring IOC 扫描器
作⽤:bean对象统⼀进⾏管理,简化开发配置,提⾼开发效率
1、设置⾃动化扫描的范围
如果bean对象未在指定包范围,即使声明了注解,也⽆法实例化
2、使⽤指定的注解(声明在类级别) bean对象的id属性默认是 类的⾸字⺟⼩写
Dao层:
	@Repository
Service层:
	@Service
Controller层:
	@Controller
任意类:
	@Component
注:开发过程中建议按照指定规则声明注解

xml配置

<!-- 设置⾃动化扫描的范围 -->
<context:component-scan base-package="com.xxxx"/>

bean的作用域和生命周期

作用域

singleton 作⽤域

lazy-init是懒加载, 如果等于true时作⽤是指Spring容器启动的时候不会去实例化这个bean,
⽽是在程序调⽤时才去实例化. 默认是false即Spring容器启动时实例化.

默认情况下,被管理的bean只会IOC容器中存在⼀个实例,对于所有获取该Bean的操作Spring容器
将只返回同⼀个Bean。

容器在启动的情况下就实例化所有singleton 的 bean对象,并缓存与容器中

prototype 作⽤域

通过scope=“prototype” 设置bean的类型 ,每次向Spring容器请求获取Bean都返回⼀个全新的
Bean,相对于"singleton"来说就是不缓存Bean,每次都是⼀个根据Bean定义创建的全新Bean。

Web应⽤中的作⽤域

request作⽤域:表示每个请求需要容器创建⼀个全新Bean。

session作⽤域:表示每个会话需要容器创建⼀个全新Bean。

globalSession作⽤域:类似于session作⽤域,其⽤于portlet

生命周期

Bean的定义、初始化、使⽤和销毁4个阶段

定义:在配置文件中定义,⼀个配置⽂档中,可以定义多个Bean。

初始化:通过指定 init-method 属性来完成

​ 实现 org.springframework.beans.factory.InitializingBean 接⼝

使用:使⽤ BeanFactory ,使⽤ ApplicationContext

销毁: 实现销毁⽅式(Spring容器会维护bean对象的管理,可以指定bean对象的销毁所要执⾏的⽅
法)
通过 AbstractApplicationContext 对象,调⽤其close⽅法实现bean的销毁过程

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值