Spring--基础介绍一:IOC和DI
前面学习了Struts2和Hibernate。
Struts2主要是用来控制业务层面逻辑和显示,告诉你什么时候走哪个action,跑去运行哪个class的什么方法,后面调到哪个jsp。
Struts2需要配置的struts.xml, 配置对应的action和jsp表单页面。
struts2包含的主要功能有哪些: 参数自动封装、参数自动转换、输入校验、拦截器、OGNL、值栈、actionContext、标签、国际化、上下文传载等。
Hibernate主要是让程序员少做Mysql操作 ,通过操作POJO这个Javabean实体来来操作数据表。---让程序员集中精力在业务上。
hibernate需要配置xxx.hbm.xml 负责映射POJO类和数据表 hibernate.cfg.xml负责连接数据库和一些数据库配置。
配置了上面两个xml就可以使用hibernate,里面也有一些特定的类:Configuration SessionFactory Session Transaction
那么Spring是用来做什么?希望 用过这个学习能明白Spring是用来干啥的,简单例子是啥?
下面文章基本是学习并参考了他们的帖子,自己按照所学实现后写的记录。想看原文请看最后附录连接!
以前也看过几次Spring,不过工作中没有用就这样忘掉了。但是其中有几个重要概念:控制反转IOC(Inverse of control),面向切面编程AOP(Aspect Oriented Programming),依赖注入DI(Dependency Injection),JavaBean等概念。现在也基本忘了。也不知道是用来干嘛的。学完后一定要能理解这个概念是用来干嘛的。
下面先来给一个例子:该添加的Jar包添加进去。
一、什么是IOC
在Spring里面也有一个配置文件:applicationContext.xml 名字不固定。就是xxx.xml用来配置bean的。
下面看我们的bean.xml, 一般直接放在src路径下:
<?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" xmlns:util="http://www.springframework.org/schema/util"
xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jpa="http://www.springframework.org/schema/data/jpa" xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">
<!-- 上面这些是标准添加 --> <!-- 配置bean Id 和对应的class,一个bean一个Id对应一个Class -->
<bean id = "computer" class="bean.Computer">
<!-- property 用来配置类的属性 -->
<property name="brand" value="HP"></property>
<property name="colour" value="Red"></property>
</bean> </beans>
上面我们在Spring容器applicationContext.xml(暂时可以这么理解)中把这个类注册为javaBean。
注意上面说的Spring容器这个概念。
然后看我们的JavaBean类Computer.java
package bean; public class Computer { private String brand;
private String colour;
/**
* @return the brand
*/
public String getBrand() {
return brand;
}
/**
* @param brand the brand to set
*/
public void setBrand(String brand) {
this.brand = brand;
}
/**
* @return the colour
*/
public String getColour() {
return colour;
}
/**
* @param colour the colour to set
*/
public void setColour(String colour) {
this.colour = colour;
}
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return "Computer [brand=" + brand + ", colour=" + colour + "]";
}
}
添加我们的测试类:
package test; import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; import bean.Computer; public class TestComputer { public static void main(String[] args) {
//定义我们配置的bean.xml
String conf = "applicationContext.xml";
//加载bean.xml
ApplicationContext ac = new ClassPathXmlApplicationContext(conf);
//通过ApplicationContext来直接获取对象,不再需要new一个实例
Computer computer = ac.getBean("computer", Computer.class);
Computer computer1 = ac.getBean(Computer.class); System.out.println(computer);
System.out.println(computer1);
} }
运行输出:
Apr 03, 2019 4:55:19 PM org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@61e717c2: startup date [Wed Apr 03 16:55:19 CST 2019]; root of context hierarchy
Apr 03, 2019 4:55:19 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [applicationContext.xml]
Computer [brand=HP, colour=Red]
Computer [brand=HP, colour=Red]
至此,这个项目就完成了,大家有没有发现什么!
我们Computer类我们没有自己实例化啊,怎么可以直接用?其实整个流程是这样的,
我们刚开始写了个Computer类;
然后在applicationContext.xml文件,即,Spring容器,把这个类注册到这个容器中,这就是一个JavaBean,并且为其属性设置了值;
接下来在TestCompute类中,实例化了这个Spring容器(不理解这句话),从这个容器中拿到Computer的类对象,并且输出。
在这个过程中我们没有自己实例化Computer类,是Spring容器帮我们实例化了,这个实例化的举动由我们程序员交给了Spring容器来实现,这就是控制反转,IOC。
所以说,所谓的控制反转,就是在Spring中我们不再需要去自己new一个实例对象,在配置好的bean.xml下,我们可以直接get对象。
到此,我们可以知道Spring的第一个功能就是帮我们创建实例。
当然Spring也同样可以通过注解来进行上面的配置,不通过bean.xml来配置。
这个地方有个需要注意的,就是一个类里面的属性不是基本数据类型,而是其他类,那么通过Spring创建这个类的时候,里面的类属性也会被赋值。(但是这个属性类是怎么被创建的呢???)
二、依赖注入(DI)
依赖注入(DI):spring创建对象A时,会将对象A所依赖的对象B也创建出来,并自动注入到对象A中。
依赖:(has a) 有一个的意思,比如类A中有一个类B,那么就说A依赖B。 继承,实现(is a)
而我们说的依赖注入,就是当创建A对象时,同时会将B对象给创建,并自动注入到对象A中去,也就说,我只叫spring给我A对象,但是A中可以使用B对象了。这个有很大的用处,但如何去实现依赖注入功能呢?下面有个例子:
package dao; public class UserDao { public void addUser(){
System.out.println("UserDao。。。。。");
System.out.println("依赖注入。。。。。");
} } package service; import dao.UserDao; public class UserService { private UserDao userDao; /**
* @param userDao the userDao to set
*/
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
} public void addUser(){
System.out.println("UserService。。。。。。。");
userDao.addUser();
} }
UserService中有使用userDao对象,这个我们都很熟悉的使用伎俩,service层调用dao层的方法。按照往常我们的写法,在service中需要自己new出UserDao对象,但是在spring中就不需要了,一切对象都让spring帮我们创建。
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" xmlns:util="http://www.springframework.org/schema/util"
xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jpa="http://www.springframework.org/schema/data/jpa" xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">
<!-- 上面这些是标准添加 --> <!-- 用来创建UserDao对象-->
<bean id = "UserDao" class = "dao.UserDao"></bean> <!-- 创建UserService对象
property对其对象中进行依赖注入过程,底层将执行setter()方法
name在UserService对象中UserDao对象的属性名
ref创建userDao对象的beanId -->
<bean id = "UserService" class = "service.UserService">
<property name="userDao" ref="UserDao"></property>
</bean> </beans>
过程如下:先创建UserService对象,然后在根据property中的ref找到userDaoId并创建UserDao对象,然后根据property中的name,通过setter方法注入,这样就完成了依赖注入。测试如下:
package service; import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class Test { public static void main(String[] args) { String conf = "applicationContext.xml"; ApplicationContext ac = new ClassPathXmlApplicationContext(conf); UserService userService = ac.getBean("UserService", UserService.class); userService.addUser();
} }
运行结果如下:
Apr 04, 2019 4:38:00 PM org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@61e717c2: startup date [Thu Apr 04 16:38:00 CST 2019]; root of context hierarchy
Apr 04, 2019 4:38:00 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [applicationContext.xml]
UserService。。。。。。。
UserDao。。。。。
依赖注入。。。。。
所谓的依赖注入:我们JavaBean中的参数都是通过setXXX()进去的,特别是当XXX不是一个基本类型数据,而是一个接口的时候,我们set进去就应该是它的实现子类。假如有多个实现子类,我们set进去是哪个就是哪个。这个就是依赖注入。所以从这个角度来看,依赖注入并不需要我们来做什么,就是一个常规 的赋值。
依赖注入也分两种方式:1:通过构造器注入; 2:通过setter方式注入
之前讲的那个依赖注入其实也属于属性依赖注入这一范畴中,在最开始我们演示IOC(控制反转)也就是spring帮我们创建实例时,那只是通过无参构造方法进行创建,那么在实际开发中,这样创建肯定是不行的,所以我们需要在spring的配置文件中配置一些属性信息,使spring帮我们创建时,可以直接将对象的一些属性也注入进去,有两种方法:
通过构造方法注入
不管是普通属性还是引用数据,都可以通过构造方法进行注入。通过setter方法进行注入,
通过setter方法对普通属性和引用属性进行注入,那么要是创建的对象中有集合呢?那该如何进入注入?
集合的注入List、Map、Set、数组、Properties等。
List
set
map
数组
propertyis
注意:properties这种类型存放形式跟map差不多,以key和value进行存放的,
到这里,基本上就把所有能够注入的属性类型都讲解完了,注入的类型基本上分为三块,普通类型,引用类型和集合。下面在讲一种基于注解来注入各种,因为基于xml感觉很麻烦。
属性依赖注入基于注解
注解格式:@xxx
使用注解:必须对使用注解的地方进行扫描,不然注解没用。而扫描需要做两件事
1、添加名称空间,
在我们找配置文件中约束的位置那:spring-framework-3.2.0.RELEASE\docs\spring-framework-reference\html\xsd-config.html 找到context的名称空间。
2、扫描指定的目录,
注解:
1、@Component 替代 <bean id="" class=""> 可以配置任意bean,在所在类上面添加该注解即可,
@Component("userId") userId相当于bean中的id属性值
2、 这三个就跟使用@Component是一样的,但是为了更好的体现三层架构,就有了这三个注解
@Controller 修饰web层中的类。
@Service 修饰service层的类
@Repository 修饰dao层的类
两种方式,一种不声明名称,一种声明名称
@Controller("xxx") @Controller
如果声明了名称,那么在别的地方引用的话,就可以使用@Autowired或@Autowired与@Qualifier的组合 或直接使用@Resource按照名称注入
如果没有声明名称,那么在别的地方引用的话,只能使用@Autowired 来进行注入
3、属性注入
普通属性
@Value @Value("") 给普通属性注入属性值
引用属性
@Autowired 按默认类型进行注入
@Qualifier("") 按照名称注入
如果使用了@Qualifier这个注解,那么就需要两个一起使用才能生效。如果只使用@Autowired,那么写不写@Qualifier都可以
引用属性
@Resource 直接按照名称注入,与上面两个注解一起使用是等效的
@Resource(name="xxx")
4、使用
5、其他注解
@Scope("prototype") 作用域注解(spring帮我们创建的bean实例的作用域,在下面会讲解到)
@PostConstruct 修饰初始化
@PreDestory 修饰销毁
最后两个用的不多,掌握前面的即可。
细细回想上面的两个概念:控制反转(IOC)和依赖注入(DI)。
https://www.cnblogs.com/whgk/p/6616593.html---
Spring--基础介绍一:IOC和DI的更多相关文章
- Spring入门一:IOC、DI、AOP基本思想
Spring框架是一个集众多涉及模式于一身的开源的.轻量级的项目管理框架,致力于javaee轻量级解决方案.相对于原来学过的框架而言,spring框架和之前学习的struts2.mybatis框架有了 ...
- Spring MVC -- Spring框架入门(IoC和DI)
Spring MVC是Spring框架中用于Web应用开发的一个模块.Spring MVC的MVC是Model-View-Controller的缩写.它是一个广泛应用于图像化用户交互开发中的设计模式, ...
- Spring学习笔记(二)Spring基础AOP、IOC
Spring AOP 1. 代理模式 1.1. 静态代理 程序中经常需要为某些动作或事件作下记录,以便在事后检测或作为排错的依据,先看一个简单的例子: import java.util.logging ...
- Spring系列三:IoC 与 DI
水晶帘动微风起,满架蔷薇一院香. 概述 在软件工程中,控制反转(IoC)是一种设计思想,对象之间耦合在一起,在运行时自动绑定,并且它们编译时对所需要引用的对象是不确定的.在这个spring教程中,通过 ...
- Spring框架中的IOC和DI的区别
上次面试被问到IOC和DI的区别时,没怎么在意,昨天又被问到,感觉有点可惜.今晚总算抽点时间,查看了spring官方文档.发现,IoC更像是一种思想,DI是一种行为.为了降低程序的耦合度,利用spri ...
- spring学习笔记之---IOC和DI
IOC和DI (一)IOC (1) 概念 IOC (Inverse of Control) 反转控制,就是将原本在程序中手动创建对象的控制权,交给spring框架管理.简单的说,就是创建对象控制权被反 ...
- Spring总结四:IOC和DI 注解方式
首先我们要了解注解和xml配置的区别: 作用一样,但是注解写在Bean的上方来代替我们之前在xml文件中所做的bean配置,也就是说我们使用了注解的方式,就不用再xml里面进行配置了,相对来说注解方式 ...
- Spring.Net 技术简介 IOC and DI
一 简单介绍 IOC 控制转移,就是将创建放到容器里,从而达到接耦合的目的,DI是 在容器创建对象的时候,DI读取配置文件,然后给对象赋默认值,两者一般结合使用,实现注入. ...
- Spring 注解方式 实现 IOC 和 DI
注:以下所有测试案例(最后一个除外)的测试代码都是同一个: package cn.tedu.test; import org.junit.Test; import org.springframewor ...
- Spring基础介绍
Spring属于轻量级还是重量级框架? 这需针对使用Spring的功能而言,比如我们常使用其核心服务整合SSH,这样则为轻量级. 如果使用其大部分服务则可以理解为重量级. 普通JAVA项目环境 ...
随机推荐
- CVTE前端一面
1.如果不设置cookie失效时间: 关闭浏览器自动关闭. 有没有手写过cookie HttpOnly 2.跨域的几种方式 如何实现cors 2.web安全: xss,csrf 如何防范 3. ...
- [C#]位运算符
参考链接: http://www.runoob.com/csharp/csharp-operators.html 表: 简单来说,就是: &:全1为1,否则为0 |:有1为1,否则为0 ^:不 ...
- Python科学计算和可视化
一.Numpy NumPy(Numeric Python)系统是 Python 的一种开源的数值计算扩展.这种工具可用来存储和处理大型矩阵,比 Python 自身的嵌套列表(nested list s ...
- 【python】python中的enumerate()函数【笔记】
结合实例来理解比较好,网上找了一下这个enumerate用法,自己也记录一下加深印象 看一下相关链接: 链接1:http://www.cnblogs.com/danielStudy/p/6576040 ...
- 如何使用cloudflare的CDN加速网站隐藏网站IP
原文:http://www.safecdn.cn/contact-zh/2018/12/cloudflare-cdn/1146.html 高防CDN:https://www.safeidc.cn/cd ...
- C++实现根据路径读取文件内容
已知文件路径,用C++实现读取对应文件的内容,代码如下: bool LoadShaderStr(const char* szShaderPath,string& strShaderStr) { ...
- 使用shell命令给文件中每一行的前面、后面添加字符
shell command shell给一个文件中的每一行开头插入字符的方法:awk '{print "xxx"$0}' fileName shell给一个文件中的每一行结尾插入字 ...
- ServletContextListener中的方法contextInitialized执行了两次
有一个web06项目是直接拷贝web05的,复制过后web06项目默认的web配置中的Context Root还是web05,导致tomcat在启动时还是会创建两个web应用,修改成web06后,cl ...
- 后台封装的easyui框架,处理texbox的时候报错:未结束的字符串常量。
原因:特殊字符导致json字符串转换成json对象出错 解决:找到初始值的地方进行过滤 代码如下: theString = theString.Replace(">", &q ...
- 如何系统的学习Java
初学者记住一点,学习Java一定是连续性的且循序渐进的“系统化”学习,首先我给你提供一个优秀Java工程师的学习路线. web前端方面:html.css,Java.jQuery.xml解析.Boots ...