java优雅的SSM框架(一):Spring框架(由浅入深,深度解读)

予象科技

发布时间:19-01-2402:07

本系列作品持续更新,包括Spring,SpringMVC,Mybatis,SpringBoot,等流行框架,由于横跨知识面积较广,时间可能要久一些,希望有意向的读者能够加一下关注,收藏,谢谢大家的支持,来自一个程序员的敬礼

优雅的SSM框架

一、Spring框架简介

1.Spring是一个开源的轻量级的应用开发框架。

2.目的是简化企业级应用程序开发,降低侵入性(程序间的耦合性)。

3.Spring是以IOC(控制反转)和AOP(面向切面)为核心的轻量级容器。

4.Spring本质是管理软件中的对象,即创建对象和维护对象之间的关系。

5.Spring对常用的API做了封装和简化

二、Spring的作用

1.管理对象(主要功能)

Spring提供了一个容器,帮助创建对象以及管理对象之间的依赖关系,降低了对象之间的耦合度,方便代码的维护。

---什么是Spring容器:Spring容器是spring框架中最核心的一个模块,用于管理对象。

2.集成其他的框架

Spring可以把其他的框架集成起来,和其他的框架联合使用

三、对Spring容器的操作—标题1

1.启动Spring容器

导包:在pom.xml文件的<dependencies></dependencies>里面配置<dependency</dependency>对

,进行导包

spring框架Maven依赖

2.用Spring容器创建对象(三种方法)

1.构造器new关键字

2.静态工厂方法:getInstance()

//启动Spring容器--默认情况下自动加载xml文件中的bean,根据每一个bean创建实例,且只创建一个对象简单的配置applicationContext.xml文件<bean id="demo01" class="com.wyq.spring.SpringDemo02"></bean><!--使用静态工厂方式创建对象factory-method 指定一个静态方法Spring容器会调用这个这个静态方法来创建对象--><bean id="calendar "class="java.util.Calendar" factory-method="getInstance"></bean>然后再java文件中用getBean()方法调用获得对象ApplicationContext ac= new ClassPathXmlApplicationContext("applicationContext.xml");SpringDemo02demo02=ac.getBean("demo01",SpringDemo02.class);

3.使用实例工厂

<!--

使用实例化工厂创建对象

factory-bean:指定工厂bean的id

factory—method:指定一个方法,Spring容器会调用这个bean对应的方法创建对象

-->

<bean id="calendar "class="java.util.Calendar" factory-method="getInstance"></bean><bean id="date" factory-bean="calendar" factory-method="getTime"></bean>

四、Spring容器的设计模式—单例模式和模型模式

1.创建对象的参数配置:

<!--

scope:设置创建对象的参数

scope属性:用来配置作用域,缺省值是singleton(即一个bean只创建一个实例)

如果值为prototype(即每次都会创建一个新的实例)

默认:singleton单例模式(饿汉式)只创建一个对象在加载xml文件时就把所有能够创建的对象都创建出来

prototype原型模式(懒加载),可以创建多个对象在要用的时候才加载对象

这里产生一个问题--怎样解决在创建对象是按需求创建对象。

--解决方法:

<!--

lazy-init:懒加载lazy-init="true"(default==false)调用的时候创建对象延时加载

在启动Spring容器时不会自动创建对象

-->

-->

<bean id="stu" class="com.wyq.spring.Stu" scope="prototype"></bean>

2.对象的生命周期配置:

对象的生命周期:new--init---service---destory创建对象Spring容器自动创建,init方法<!--init-method属性:创建emp对象后直接调用init()方法--><!--destroy-method:销毁时执行的方法destory()//关闭Spring容器销毁创建的对象只在单例模式下才会执行销毁//在原型模式下是不会销毁对象--><bean id="emp" class="com.wyq.spring.Emp" init-method="init" destroy-method="destory" scope="prototype"></bean>

3.对象的销毁:

对象的销毁 关闭Spring容器销毁对象 关闭Spring容器的方法:

((ClassPathXmlApplicationContext)applicationContext).close();

五、Spring对于对象的解耦操作 IOC

1.IOC(控制反转):

IOC:spring的核心---控制反转 由容器来管理对象之间的依赖关系

DI:依赖注入:容器通过调用对象提供的set方法或者构造器来建立依赖关系。

IDC是目标 DI是手段

2.IOC注入方式:set注入、构造器、自动装载

1.Set注入:

配置文件

<!--

property:特性属性

注入:ref:连接对应id的bean创建对象指向id值id值是唯一的

怎么注入:property元素使用set方法来注入依赖

怎么调用set方法??把name的属性值首字母大写并转化为对应的方法名setA

该setA和B.class里面的setA方法名一样这样就找到了相对应的方法

-->

<bean id="a" class="com.wyq.test.A"></bean><bean id="b" class="com.wyq.test.B"><property name="a"ref="a"></property></bean>

A类

public class A {publicA(){System.out.println("A --- A");}public voidf1(){System.out.println("A --- f1");}}

B类

public class B {private A a;publicB(){System.out.println("B -- B");}public voidsetA(A a) {this.a = a;}public voidexecute(){a.f1();}}

测试类

@Testpublic void test01(){ApplicationContext applicationContext= new ClassPathXmlApplicationContext("applicationContext.xml");applicationContext.getBean("b",B.class).execute();}

set注入的使用步骤:提供set方法-----配置<property>元素的属性 name, ref, value

2.构造器注入:

配置文件

<!--

构造器注入:

1.添加对应的构造方法

2.配置constructor-arg元素

-->

<bean id="m" class="com.wyq.test02.Man"></bean><bean id="w" class="com.wyq.test02.Woman"></bean><bean id="person" class="com.wyq.test02.Person"><constructor-arg index="0" ref="m"></constructor-arg><constructor-arg index="1" ref="w"></constructor-arg></bean>

Peson类

public class Person{private Man man;private Woman woman;Public Person(){System.out.println("person");}public Person (Manman,Womanwoman){this.man=man;this.woman=woman;}public void execute(){man.m();woman.w();}}

Man类

public class Man{public Man(){System.out.println("m");}public void m(){System.out.println("man---f");}}

Woman类

public class Woman{public Woman(){System.out.println("w");}public void w(){System.out.println("woman---f");}}

@Testpublic void test02(){ApplicationContext applicationContext= new ClassPathXmlApplicationContext("applicationContext.xml");applicationContext.getBean("person",Person.class).execute();}

3.自动装配:

配置文件

<!--

自动装配 autowire:不常用

byName:通过自动调用set方法完成调用,底层的实现是set注入,

根据id查找并将id的首字母大写,找到相应的set方法,找到唯一的对象

byType:

constructor:

default:

-->

<bean id="teacher" class="com.wyq.test03.Teacher"></bean><bean id="student" class="com.wyq.test03.Student" autowire="byName"></bean>

Teacher类

public class Teacher {publicTeacher(){}public voidteach(){System.out.println("teacher -- teach");}}

Student类

public class Student {privateTeacher teacher;public voidsetTeacher(Teacher teacher){this.teacher = teacher;}public voidexecute(){teacher.teach();}}

@Testpublic void test03(){ApplicationContext applicationContext = newClassPathXmlApplicationContext("applicationContext.xml");applicationContext.getBean("student", Student.class).execute();}

3.Spring的参数注入和基于注解的组件扫描

1.参数注入:依赖于getter和setter方法

1.getter、setter方法:

<!--

根据<property>标签里面的name属性找到对应的set方法,然后将标签里面的value的值赋值给相应的属性

实际上name属性的值对应的就是类中的属性的引用

<value/>元素可以通过字符串指定属性或构造器参数的值,也可以通过value属性指定基本值

1.给参数赋值

2.给集合赋值 list:<list> set:<set> map:<map> properties:<props>

-->

<bean id="value" class="com.wyq.test04.ValueBean"><!--1.给参数赋值--> <property name="age" value="13"></property> <property name="name" value="www"></property> <!--2.给集合赋值--> <property name="list"> <list> <value>张三</value> <value>李四</value> <value>王五</value> </list> </property> <property name="set"> <set> <value>321</value> <value>534</value> <value>4354</value> </set> </property> <property name="map"> <map> <entry key="name" value="李四"></entry> <entry key="sex" value="男"></entry> <entry key="age" value="43"></entry> </map> </property> <property name="properties"> <props> <prop key="name">张三</prop> <prop key="age">23</prop> </props> </property></bean>

/**

* 给基本数据注入赋值

*/

public class ValueBean {//给基本数据类型注入值 int age; //给字符串注入值 String name; //给list集合注入值 private List<String> list; //给set集合注入值 private Set<String> set; //给map集合注入值 private Map<String,String> map; //给Properties注入值 private Properties properties; getter(); setter(); toString();}

/**

* 测试参数注入

*/

@Testpublic void test04(){ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); ValueBean value = applicationContext.getBean("value", ValueBean.class); System.out.println(value);}

2.引用注入:

<!--

引用注入

设置id,根据id找相应的内容,<util:list>相当于一个对象

-->

<util:list id="list1"><value>1</value> <value>2</value> <value>3</value> <value>4</value></util:list><util:properties id="pro"> <prop key="name">www</prop> <prop key="sex">m</prop> <prop key="age">33</prop></util:properties><bean id="value2" class="com.wyq.test04.ValueBean"> <property name="list" ref="list1"></property> <property name="properties" ref="pro"></property></bean>

读取properties文件中的配置内容

<!--

读取properties文件

classpath属性: properties文件对应的路径,一般直接写配置的名称和类型

读取文件的内容返回properties对象

1.创建properties文件

2.配置xml文件

3.启动spring容器获得properties对象

-->

<util:properties id="pro2" location="classpath:config.properties"></util:properties>

3.Spring表达式:

<!--

spring表达式 #{}

通过Spring表达式获取properties文件中的值向对象中的属性注入值

-->

<util:properties id="pro2" location="classpath:config.properties"></util:properties><bean id="propertiesBean" class="com.wyq.test04.PropertiesBean"><property name="name" value="#{pro2.name}"></property> <property name="age" value="#{pro2.age}"></property> <property name="sex" value="#{pro2.sex}"></property></bean>

//测试用的类

public class PropertiesBean {private String name; private String age; private String sex; public void setAge(String age) { this.age = age; } public void setName(String name) { this.name = name; } public void setSex(String sex) { this.sex = sex; } @Override public String toString() { return "properties name="+name+" age="+age+" sex="+sex; }}

2.注解扫描:减少xml文件的书写量

1.注解扫描:

/**

* 注解扫描 组件扫描

* 什么是组件扫描:指定一个包路径,Spring会自动扫描包及其子包所有的组件类

* 当发现组件定义前有特定的注解标记时,

* 就将该组件纳入到Spring容器,等价于原有XML配置中的<bean>定义功能

* 组件扫描可以替代大量XML配置的<bean>定义

*

常用注解

2.注解步骤及常用注解:

<!--

注解的第一步

1.打开spring注解扫描

base-package:指定要扫描的包,Spring会自动扫描该包以及其子包的路径

如果该包下面有特定的注解,则Spring容器会将其纳入容器进行管理,相当于配置一个bean类

当一个组件在扫描扫描过程中被检测到时,会生成一个默认id值,

默认id为小写开头的类名,也可以在注解标记中自定义id,

-->

<context:component-scan base-package="com.wyq.test05"></context:component-scan>

----注解实例:

@Scope("prototype")//注解成原型模式 不加这个注解默认是单例模式

@Component("emp")//创建对象的注解 ("emp")表示自定义的id

@Lazy(true)//懒加载的注解

public class Emp {private Dept dept; @Resource(name = "dept") //具有依赖关系的Bean对象的注解 public void setDept(Dept dept) { System.out.println("set依赖注入---"+dept); this.dept = dept; }//1.使用组件扫描,首先需要在XML配置中指定扫描路径 public Emp(){ System.out.println("emp --- 组件扫描"); } //2.当一个组件在扫描过程中被检测到时,会生成一个默认id值, //默认id为小写开头的类名,也可以在注解标记中自定义id, //3.开启Spring容器 根据id获取到相应的对象 @Override public String toString() { return "emp 组件扫描"; } @PostConstruct //注解生成初始化方法 public void init(){ System.out.println("init 方法 初始化"); } @PreDestroy //注解生成销毁方法 public void destory(){ /** * 原型模式下不能进行调用销毁方法* 单例模式下可以进行调用 */ System.out.println("销毁的方法"); }}

/**

*指定依赖注入的关系

*/

@Component("dept")//将类添加进Spring进行管理

public class Dept {public Dept(){ System.out.println("dept -- dept"); } @Override public String toString() { return "dept 的toString方法"; }}

本系列作品持续更新,包括Spring,SpringMVC,Mybatis,SpringBoot,等流行框架,由于横跨知识面积较广,时间可能要久一些,希望有意向的读者能够加一下关注,收藏,谢谢大家的支持,来自一个程序员的

返回顶部