2019年(25)
分类: Java
2019-10-17 11:35:34
一、概述
1.1、什么是Spring
Spring是一个一站式、开源、低侵入式、轻量级框架,它的核心理念是IoC (Inversion of Control,控制反转) 和 AOP(Aspect Oriented Programming,面向切面编程),可以适用于任何Java程序,方便Java开发,是每一个Java Coder的必备技能。
1.2、术语介绍
框架:是能完成一定功能的半成品。框架帮助我们完成了一部分功能,比如:整体架构、资源管理、问题解决方案等。我们自己再完成业务,那这个项目就完成了。
一站式:夸这个spring框架很“全面”且整合度高,提供IOC管理维护对象和AOP编写事务日志等模块,提供SpringMVC与用户交互,提供JDBCTemplate与数据库交互数据等技术。
开源:Sparing框架的源码对外开放,我们可以到git上下载源码,开源意味着全世界的Spring爱好者们可以参与到Spring框架的优化设计上,使该框架越来越好,同时知道源代码如何编写,对深入学习Spring框架也有很大好处,当然开源就也意味着免费。
低侵入式:侵入式代表使用该技术是否要求你的程序必须继承或者实现框架中的类或接口,在切换技术时就是一场灾难,而Spring是一个低侵入式的框架,不需要程序强制的实现或继承Spring中的接口和类。
轻量级:轻量级是相对于重量级而言的,轻量级一般就是非入侵性的、所依赖的东西非常少、资源占用非常少、部署简单等等,其实就是比较容易使用,而重量级正好相反。
JavaBean:属性私有,有Getter和Setter方法,无参的构造方法,这个类就符合JvaBean规范,就是一个JavaBean,JavaBean一般用来存储对象数据。
容器:在日常生活中容器就是一种盛放东西的器具,从程序设计角度看就是装对象的的对象,我们可以放入和拿出对象,容器也管理对象生命周期,我们使用的Tomcat其实也是一个Web容器,用来存放web程序。
1.3、Spring的优势
低侵入 / 低耦合 (降低组件之间的耦合度,实现软件各层之间的解耦)
声明式事务管理(基于切面和惯例)
方便集成其他框架(如MyBatis、Hibernate等)
降低 Java 开发难度
Spring 框架中包括了 J2EE 三层的每一层的解决方案(一站式)
1.4、Spring能帮我们做什么
1、Spring 能帮我们根据配置文件创建及组装对象之间的依赖关系。
2、Spring 面向切面编程能帮助我们无耦合的实现日志记录,性能统计,安全控制。
3、Spring 能非常简单的帮我们管理数据库事务。
4、Spring 还提供了与第三方数据访问框架(如Hibernate、JPA)无缝集成,而且自己也提供了一套JDBC访问模板来方便数据库访问。
5、Spring 还提供与第三方Web(如Struts1/2、JSF)框架无缝集成,而且自己也提供了一套Spring MVC框架,来方便web层搭建。
6、Spring 能方便的与Java EE(如Java Mail、任务调度)整合,与更多技术整合(比如缓存框架、消息队列等)。
1.5、架构
Data Access/Integration层包含有JDBC、ORM、OXM、JMS和Transaction模块。
Web层包含了Web、Web-Servlet、WebSocket、Web-Porlet模块。
AOP模块提供了一个符合AOP联盟标准的面向切面编程的实现。
Core Container(核心容器):包含有Beans、Core、Context和SpEL模块。
Test模块支持使用JUnit和TestNG对Spring组件进行测试。
二、IOC和DI
2.1、IoC:Inverse of Control(控制反转)
2.1.1、IOC概述
读作“反转控制”,更好理解,不是什么技术,而是一种设计思想,就是将原本在程序中手动使用new关键字创建对象的控制权,交由Spring框架来管理。
正控:若要使用外汇返佣某个对象,需要自己去负责对象的创建
反控:若要使用某个对象,只需要从 Spring 容器中获取需要使用的对象,不关心对象的创建过程,也就是把创建对象的控制权反转给了Spring框架
2.1.2、创建名为spring的项目
使用IDEA通过Maven构建项目
2.1.3、pom依赖
2.1.4、创建spring配置文件
在resources目录下创建applicationContext.xml配置文件
2.2.4、测试
package com.stt.test;
import com.stt.pojo.Fruit;
import com.stt.pojo.Person;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* ClassName: SpringTest
*/
public class SpringTest {
public static void main(String[] args) {
//读取applicationContext.xml配置文件,获取applicationContext对象
ClassPathXmlApplicationContext applicationContext =
new ClassPathXmlApplicationContext("applicationContext.xml");
//通过applicationContext对象获取spring容器中的对象,我们来获取fruit对象
//Fruit fruit = (Fruit)applicationContext.getBean("fruit");
//打印
//System.out.println(fruit);
Person person = (Person) applicationContext.getBean("person");
person.eat();
}
}
结果:
2.2.5、总结
1、DI其实就是对属性进行赋值,可以是一个普通的变量(String),也可以是一个对象(Fruit)甚至是一个集合
2、注入值在bean标签中使用property标签,注入固定的值使用value属性,注入其他的IOC中的对象使用ref,填写在IOC中id属性值即可
3、类中一定要写set方法,因为注入值是使用set方法注入的
4、IOC可以单独存在使用,而DI需要依赖于IOC
2.3、IOC原理
这是我们本章节的重点,我们知道了IOC可以帮助我们创建对象,那么它到底是如何创建的对象,我们一起来学习一下
1、读取配置文件或者注解,看看Person依赖的是哪个Fruit,拿到类的全路径也就是包名.类名
2、通过Jva中的反射,基于类名调用getInstance()方法,该方法回去调用类中的无参构造进行实例化,所以类中必须有个一个无参构造
3、将对象实例,通过构造函数或者 setter,传递给 Person
我们也可以自己通过编码方式实现IOC,但是没有必要重复造轮子,但是需要知道轮子是如何创造出来的。可以通过阅读Spring源码具体了解Spring中的IOC实现的具体细节
三、注解方式实现IOC和DI
3.1、背景
我们上边的案例使用xml配置通过bean标签和property标签实现IOC和DI,如果我们有很多对象需要Spring帮助我们管理编写xml文件将非常繁琐,Spring2.X的推出伴随着JDK1.5的诞生支持了通过注解的方式实现IOC和DI,极大的简化了我们的开发
3.2、编码实战
3.2.1、applicationContext.xml
xmlns:context="http://www.springframework.org/schema/context"
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
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
该配置文件需要添加context约束,使用context:component-scan开启包扫描,填写自己的包名,可以找到我们编写的注解。
3.2.2、Fruit类
package com.stt.pojo;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
/**
* ClassName: Fruit
* 使用@Component注解创建对象,相当于bean标签,value属性相当于id属性
* 意思是创建Fruit类的对象存储在IOC容器中,在IOC中名字为fruit
* 使用Value注解来为属性注入固定的值
*/
@Component(value = "fruit")
public class Fruit {
@Value("芒果")
private String name;//水果名
@Value("黄色")
private String color;//颜色
@Value("芒果味")
private String taste;//口味
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public String getTaste() {
return taste;
}
public void setTaste(String taste) {
this.taste = taste;
}
@Override
public String toString() {
return name+"的味道是"+taste+"颜色是"+color;
}
}
3.2.3、Person类
1、使用Resource注解注入Fruit对象
package com.stt.pojo;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* ClassName: Person
*/
@Component(value = "person")
public class Person {
@Value("小明")
private String name;//名字
//使用Resource注解引用IOC容器中的对象给属性赋值
@Resource(name = "fruit")
private Fruit fruit;//水果
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Fruit getFruit() {
return fruit;
}
public void setFruit(Fruit fruit) {
this.fruit = fruit;
}
//吃水果方法
public void eat(){
System.out.println(name+"吃一个"+fruit.getColor()+"的"+fruit.getName()+"觉得很"+fruit.getTaste());
}
}
2、使用Autowired注解注入Fruit对象
package com.stt.pojo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* ClassName: Person
*/
@Component(value = "person")
public class Person {
@Value("小明")
private String name;//名字
//使用Resource注解引用IOC容器中的对象给属性赋值
//@Resource(name = "fruit")
@Autowired
private Fruit fruit;//水果
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Fruit getFruit() {
return fruit;
}
public void setFruit(Fruit fruit) {
this.fruit = fruit;
}
//吃水果方法
public void eat(){
System.out.println(name+"吃一个"+fruit.getColor()+"的"+fruit.getName()+"觉得很"+fruit.getTaste());
}
}