[Spring+SpringMVC+Mybatis]框架学习笔记(二):Spring-IOC-DI
上一章:[Spring+SpringMVC+Mybatis]框架学习笔记(一):SpringIOC概述
下一章:[Spring+SpringMVC+Mybatis]框架学习笔记(三):Spring实现JDBC
第2章 Spring-IOC-DI
Spirng的IOC(控制反转)是通过依赖注入(dependency injection)来实现的。
优点:
- 大量减少了对象的创建和管理,使代码层次更加清晰;
- Spring的IOC容器是一个轻量级的容器,没有入侵性(不依赖容器的API),不需要实现一些特殊的接口,这是一个合理设计的基本要求;
- 鼓励我们面向接口编程;
- 减少代码的耦合,将耦合的部分推到了配置文件中,如果他们的关系发生了改变,只需要修改配置文件;
- 提供了aop声明式的服务能力。
2.1 基于xml配置文件的注入
基于xml文件配置的注入:
- 构造函数注入
- setter方法注入
- 特定接口注入(用的少,省略)
前两种详见第1章.
2.1.1 常见pojo类属性的注入
pojo类:没有实现任何接口和继承任何父类的简单的java类
1)bean
package com.steven.spring.sysmgr.entity;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* 用于测试pojo对象常见属性的注入
* @author chenyang
*
*/
public class User {
private String strValue;
private int intValue;
private List listValue;
private Set setValue;
private String[] strArrayValue;
private Map mapValue;
public String getStrValue() {
return strValue;
}
public void setStrValue(String strValue) {
this.strValue = strValue;
}
public int getIntValue() {
return intValue;
}
public void setIntValue(int intValue) {
this.intValue = intValue;
}
public List getListValue() {
return listValue;
}
public void setListValue(List listValue) {
this.listValue = listValue;
}
public Set getSetValue() {
return setValue;
}
public void setSetValue(Set setValue) {
this.setValue = setValue;
}
public String[] getStrArrayValue() {
return strArrayValue;
}
public void setStrArrayValue(String[] strArrayValue) {
this.strArrayValue = strArrayValue;
}
public Map getMapValue() {
return mapValue;
}
public void setMapValue(Map mapValue) {
this.mapValue = mapValue;
}
}
2)配置文件applicationContext-property.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 http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="user" class="com.steven.spring.sysmgr.entity.User">
<property name="strValue" value="abc"/>
<property name="intValue" value="123"/>
<property name="listValue">
<list>
<value>list1</value>
<value>list2</value>
<value>list3</value>
</list>
</property>
<property name="setValue">
<set>
<value>set1</value>
<value>set2</value>
<value>set3</value>
</set>
</property>
<property name="strArrayValue">
<list>
<value>strArray1</value>
<value>strArray2</value>
<value>strArray3</value>
</list>
</property>
<property name="mapValue">
<map>
<entry key="key1" value="map1"></entry>
<entry key="key2" value="map2"></entry>
<entry key="key3" value="map3"></entry>
</map>
</property>
</bean>
</beans>
3)测试类
package com.steven.spring.sysmgr.action;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.steven.spring.sysmgr.entity.User;
/**
* 测试bean的属性的注入
* @author chenyang
*
*/
public class PropertyDITest {
@Test
public void testPropertyDI(){
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext-property.xml");
User user = (User) ac.getBean("user");
System.out.println("strValue : " + user.getStrValue());
System.out.println("intValue : " + user.getIntValue());
System.out.println("listValue : " + user.getListValue());
System.out.println("setValue : " + user.getSetValue());
System.out.println("strArrayValue : " + user.getStrArrayValue());
System.out.println("mapValue : " + user.getMapValue());
}
}
测试结果:
strValue : abc
intValue : 123
listValue : [list1, list2, list3]
setValue : [set1, set2, set3]
strArrayValue : [Ljava.lang.String;@71def8f8
mapValue : {key1=map1, key2=map2, key3=map3}
2.1.2 bean的scope属性
bean的scope属性代表bean对象的作用域,scope=“singleton/prototype”
- singleton 仅初始化一次,创建一个实例 A a = new A() 相当于单例模式
- prototype 每次对bean的访问都会重新创建一个新的实例 相当于多例模式
1)配置文件applicationContext-scope.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 http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- scope属性表示单例/多例,属性值singleton(默认)/prototype-->
<bean id="userOther" class="com.steven.spring.sysmgr.entity.UserOther" scope="prototype"></bean>
</beans>
2)测试类(实体类UserOther略)
package com.steven.spring.sysmgr.action;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.steven.spring.sysmgr.entity.UserOther;
/**
* 测试bean的scope属性
* @author chenyang
*
*/
public class ScopeDITest {
private ApplicationContext ac;
@Before
public void init(){
ac = new ClassPathXmlApplicationContext("applicationContext-scope.xml");
}
@Test
public void testScopeDI(){
UserOther userOther1 = (UserOther) ac.getBean("userOther");
UserOther userOther2 = (UserOther) ac.getBean("userOther");
System.out.println(userOther1.toString());
System.out.println(userOther2.toString());
System.out.println(userOther1 == userOther2);
}
}
2.1.3 bean的延迟加载
- 在bean标签里面写入lazy-init=”false/true”,当为false时,容器启动时加载;当为true时,启动时不加载,使用时加载;
- 在bean的头文件里面写入default-lazy-init=”true” 代表整个配置文件的对象都是延迟加载的。
1)配置文件applicationContext-lazyInit.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 http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 延迟加载lazy-init属性,默认值false -->
<!-- 这里为了模拟出延迟加载的效果,故意将class值写错 -->
<bean id="userAnOther" class="com.steven.spring.sysmgr.entity.UserAnotherError" lazy-init="true"></bean>
</beans>
2)测试类
package com.steven.spring.sysmgr.action;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* 测试bean的scope属性
* @author chenyang
*
*/
public class LazyInitTest {
private ApplicationContext ac;
@Before
public void init(){
ac = new ClassPathXmlApplicationContext("applicationContext-lazyInit.xml");
}
@Test
public void testLazyInit(){
//若lazy-init为false,这句不会打印,直接报错;若为true,这句打印后报错
System.out.println("---------容器已启动--------");
ac.getBean("userAnOther");
}
}
2.1.4 bean的自动装配(autowire)
spring可以自动的向bean中注入依赖 ----> 自动装配(autowire),其底层都是通过setter方式注入:
- byName 定义的依赖的bean名称需要与类中引用的名称一致,就会匹配依赖关系;
- byType 通过定义的依赖bean 的类型来进行匹配.
ps:建议不要在配置文件里面用自动装配,虽然可以减少配置文件,但是不利于维护。这里讲主要是后面注解部分要用到。
1)服务类UserService和Dao类IUserDao、UserDaoImplJdbc和UserDaoImplOther与第1章中例子中相同,这里略
2)配置文件applicationContext-autowire.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 http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 自动装配autowire,它有两个属性值:byName/byType -->
<bean id="userDao" class="com.steven.spring.sysmgr.dao.impl.UserDaoImplJdbc"></bean>
<bean id="userDaoImplOther" class="com.steven.spring.sysmgr.dao.impl.UserDaoImplOther" autowire-candidate="false"></bean>
<!-- byName: 它是根据类UserService中所依赖的类的引用的名称(userDao),在本配置文件中去寻找对应的bean的id,这里即为userDao -->
<bean id="userServiceByName" class="com.steven.spring.sysmgr.service.UserService" autowire="byName"></bean>
<!-- byType: 它是根据类UserService中所依赖的类的类型来匹配,只要类型一致即可(包含实现或子类),那么这里就会匹配两个,就会报错,因此就需要在不需匹配的bean标签中加上 autowire-condidate="false",该属性默认值为true -->
<bean id="userServiceByType" class="com.steven.spring.sysmgr.service.UserService" autowire="byType"></bean>
</beans>
3) 测试类
package com.steven.spring.sysmgr.action;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.steven.spring.sysmgr.service.UserService;
public class AutoWireTest {
ApplicationContext ac;
@Before
public void init(){
ac = new ClassPathXmlApplicationContext("applicationContext-autowire.xml");
}
//测试自动装配byName方式
@Test
public void testAutoWireByName(){
UserService userService = (UserService)ac.getBean("userServiceByName");
userService.loginUser("abc", "123");
}
//测试自动装配byType方式
@Test
public void testAutoWireByType(){
UserService userService = (UserService)ac.getBean("userServiceByType");
userService.loginUser("abc", "123");
}
}
2.2 配置文件的加载方式
2.2.1 单个配置文件
- 根据类的相对路径加载:
ApplicationContext ac = new FileSystemXmlApplicationContext("applicationContext.xml"); - 根据文件的绝对路径加载:
ApplicationContext ac = new FileSystemXmlApplicationContext("E:\\spring02-IOC-DI\\\src\\\applicationContext.xml");
2.2.2 多个配置文件
1)测试类:
package com.steven.spring.sysmgr.action;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* 测试不同方式加载多个spring配置文件
* @author chenyang
*
*/
public class ConfigFilesLoadTest {
@Test
public void testConfigFilesLoad(){
//方式1: 按照单个配置文件逐个加载,此处略
//方式2:罗列或数组
//罗列的方式
/*ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml",
"applicationContext-property.xml",
"applicationContext-scope.xml");*/
//数组的方式
/*String[] configFiles = new String[]{
"applicationContext.xml",
"applicationContext-property.xml",
"applicationContext-scope.xml"};
ApplicationContext ac = new ClassPathXmlApplicationContext(configFiles);*/
//方式3:字符串匹配的方式
/*ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext*.xml");*/
//方式4:总配置文件的方式
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext-all.xml");
}
}
2)总配置文件applicationContext-all.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 http://www.springframework.org/schema/beans/spring-beans.xsd">
<import resource="applicationContext.xml"/>
<import resource="applicationContext-property.xml"/>
<import resource="applicationContext-scope.xml"/>
</beans>
2.3 基于注解的注入
- 引入jar包:spring-aop-4.2.1.RELEASE.jar
- 在xml配置文件里加入约束
- 在xml配置文件里定义扫描需要用到的包的路径
- 在需要注解的bean对象前面加入注解标识符
- @Component("") 通用型
- @Service("") 一般用于声明服务类
- @Repository("") 一般用于声明DAO类
- @Controller("") 一般用于声明控制类(springMVC/struts2 action/controller)
- @Scope(""singleton/prototype") 声明单例/多例
- 声明依赖关系
- @Resource 默认是用byName的方式注入,实在找不到,就用byType方式
- @Autowired 默认是用byType的方式注入,但如果遇到多个,然后用byName的方式
- @Qualifier("") 指定需要的对象的名称,需与Autowired配合使用,不能单独使用
注意(面试):
注解方式一般原则上不需要设置setter 方法,但一般都写上。因为当我们通过配置文件的方式进行了部分DI,若没有setter 方法,就会报异常。
这里借用第1章中的例子。
1)配置文件applicationContext.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 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.steven.spring.sysmanage"></context:component-scan>
</beans>
2)服务类
package com.steven.spring.sysmanage.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.steven.spring.sysmanage.dao.IUserDao;
/**
* 用于用户登录、增删改查的服务类
* @author Administrator
*
*/
//说明当前类是一个组件,相当于在配置文件中加入的对应的bean标签
//@Component("userService")
@Service("userService")
public class UserService {
@Autowired //默认是用byType的方式注入,但如果遇到多个,然后用byName的方式
//@Qualifier("userDaoOther") //指定需要的类的名称,需与Autowired配合使用,不能单独使用
//@Resource //默认是用byName的方式注入,实在找不到,就用byType方式
IUserDao userDao;
public void setUserDao(IUserDao userDao) {
this.userDao = userDao;
}
/**
* 通过调用与数据库交互的UserDao里面的loginUser方法,判断是否验证成功
* @param userName
* @param password
* @return
*/
public boolean loginUser(String userName, String password){
boolean flag = false;
flag = userDao.loginUser(userName, password);
return flag;
}
}
3)DAO类
package com.steven.spring.sysmanage.dao.impl;
import org.springframework.stereotype.Repository;
import com.steven.spring.sysmanage.dao.IUserDao;
//@Component("userDao")
@Repository("userDao")
public class UserDao implements IUserDao {
public boolean loginUser(String userName, String password) {
System.out.println("这是通过JDBC进行登录验证的DAO方法");
return true;
}
}
package com.steven.spring.sysmanage.dao.impl;
import org.springframework.stereotype.Repository;
import com.steven.spring.sysmanage.dao.IUserDao;
//@Component("userDaoOther")
@Repository("userDaoOther")
public class UserDaoOther implements IUserDao {
public boolean loginUser(String userName, String password) {
System.out.println("这是通过其它方式进行登录验证的DAO方法");
return true;
}
}
4)测试类
package com.steven.spring.sysmanage.test;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.steven.spring.sysmanage.service.UserService;
/**
* 测试使用注解的方式实现DI
* @author Administrator
*
*/
public class AnnotationTest {
@Test
public void testDI(){
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService = (UserService) ac.getBean("userService");
userService.loginUser("abc", "123");
}
}
上一章:[Spring+SpringMVC+Mybatis]框架学习笔记(一):SpringIOC概述
下一章:[Spring+SpringMVC+Mybatis]框架学习笔记(三):Spring实现JDBC
[Spring+SpringMVC+Mybatis]框架学习笔记(二):Spring-IOC-DI的更多相关文章
- [Spring+SpringMVC+Mybatis]框架学习笔记(六):事务
第7讲 事务 7.1 事务的概念 事务是一系列作为一个逻辑单元来执行的操作集合. 它是数据库维护数据一致性的单位,它讲数据库从一个一致状态,转变为新的另外一个一致状态.说的简单一点就是:如果一组处理步 ...
- 用IntelliJ IDEA 开发Spring+SpringMVC+Mybatis框架 分步搭建二:配置MyBatis 并测试(1 构建目录环境和依赖)
引言:在用IntelliJ IDEA 开发Spring+SpringMVC+Mybatis框架 分步搭建一 的基础上 继续进行项目搭建 该部分的主要目的是测通MyBatis 及Spring-dao ...
- 用IntelliJ IDEA 开发Spring+SpringMVC+Mybatis框架 分步搭建二:配置MyBatis 并测试(2 配置spring-dao和测试)
用IntelliJ IDEA 开发Spring+SpringMVC+Mybatis框架 分步搭建二:配置MyBatis 并测试(1 搭建目录环境和依赖) 四:在\resources\spring 下面 ...
- Spring+SpringMVC+MyBatis集成学习笔记【一】
一,首先要清楚,SpringMVC其实就是Spring的一个组件 例如我们知道Spring中有类似于,AOP TX等等类似的组件,所以SpringMVC其实就是Spring的一个组件,是S ...
- 搭建Spring + SpringMVC + Mybatis框架之三(整合Spring、Mybatis和Spring MVC)
整合Spring和SpringMVC 之前已经整合了spring和mybatis,现在在此基础上整合SSM. 项目目录: 思路:SpringMVC的配置文件独立,然后在web.xml中配置整合. (1 ...
- 用IntelliJ IDEA 开发Spring+SpringMVC+Mybatis框架 分步搭建三:配置spring并测试
这一部分的主要目的是 配置spring-service.xml 也就是配置spring 并测试service层 是否配置成功 用IntelliJ IDEA 开发Spring+SpringMVC+M ...
- 用IntelliJ IDEA 开发Spring+SpringMVC+Mybatis框架 分步搭建一:建立MAVEN Web项目
一:创建maven web项目er
- Spring+SpringMVC+MyBatis深入学习及搭建(二)——MyBatis原始Dao开发和mapper代理开发
转载请注明出处:http://www.cnblogs.com/Joanna-Yan/p/6869133.html 前面有写到Spring+SpringMVC+MyBatis深入学习及搭建(一)——My ...
- Spring+SpringMVC+MyBatis深入学习及搭建(十二)——SpringMVC入门程序(一)
转载请注明出处:http://www.cnblogs.com/Joanna-Yan/p/6999743.html 前面讲到:Spring+SpringMVC+MyBatis深入学习及搭建(十一)——S ...
- Spring+SpringMVC+MyBatis深入学习及搭建(十二)——SpringMVC入门程序
转载请注明出处:http://www.cnblogs.com/Joanna-Yan/p/6999743.html 前面讲到:Spring+SpringMVC+MyBatis深入学习及搭建(十一)--S ...
随机推荐
- include-file
0X01 前言 这篇文章介绍文件包含漏洞. 0X02 最常见的两个函数的形象解释: 我们知道文件包含最常见的是两个函数 include() require()(这里就不谈他们的亲戚 include_o ...
- 点&边双连通分量
双连通分量 参考博客:https://www.cnblogs.com/jiamian/p/11202189.html#_2 概念 双连通分量有点双连通分量和边双连通分量两种.若一个无向图中的去掉任意一 ...
- Prism Sample 13-IActiveAwareCommands
本例和12的唯一区别,仅仅是在ViewModel中增加了一个IActiveAware,这决定了只有在Acitve状态的视图中才会执行自己ViewModel中的命令.
- 【CSS】画出宽度为1像素的线或边框
由于多倍的设计图在移动设备上显示时会将设计图进行缩小到视口宽度,而1px的边框没有随着页面进行缩小而导致效果太粗,想要还原设计图1px的显示效果,因此需要一些方法来实现边框宽度小于1px. 实现方法很 ...
- IIS6网站批量迁移至IIS7经验分享
迁移原因:公司服务器更换 迁移环境:源服务器 windows2003 X86 IIS6 目标服务器:windows2008 X64 IIS7 迁移过程: 第一次迁移失败,作为简要记 ...
- 2022-01-21:完美矩形。 给你一个数组 rectangles ,其中 rectangles[i] = [xi, yi, ai, bi] 表示一个坐标轴平行的矩形。这个矩形的左下顶点是 (xi,
2022-01-21:完美矩形. 给你一个数组 rectangles ,其中 rectangles[i] = [xi, yi, ai, bi] 表示一个坐标轴平行的矩形.这个矩形的左下顶点是 (xi, ...
- vue全家桶进阶之路28:项目仓库Gitee
Gitee(之前称为GitCafe)是一种基于web的Git仓库托管服务,在中国很受欢迎.它为开发人员提供了一个平台,可以托管他们的Git仓库,与其他开发人员协作,并管理他们的代码. https:// ...
- Solon 用 throw 抛出数据
此文主要是想在观念上有所拓展.在日常的接口开发时,数据的输出可以有两种方式: 返回(常见) 抛出(可以理解为越级的.越类型的返回) 我们经常会看到类似这样的案例.为了同时支持正常的数据和错误状态,选择 ...
- 第一单元 .Net 平台介绍
第一单元 .Net 平台介绍 学习编程,电脑基本配置(当然配置越高越好): 内存 :初期学习8 G,后期可能跟不上, 最好16 G以上 硬盘:500 G,5400 转速,至少C盘是固态,全是固态最好 ...
- 每周更新 | Verilog测试用例及波形展示图功能上线
Hi,亲爱的技术伙伴,经过产研团队的努力,本周ShowMeBug有以下4个功能上线啦- 芯片语言 Verilog 支持测试用例 芯片语言 Verilog 支持测试用例,自动评分同步上线- 同时,Ver ...