Spring
1. spring简介
- Spring是一个轻量级的控制反转【IOC】和面向切面【AOP】的(容器)框架。(没有任何其他的依赖,使用他,不需要导入其他的包。)
- spring是开源的,免费的。
- Spring 框架是一个分层架构,由 7 个定义良好的模块组成。Spring 模块构建在核心容器之上,核心容器定义了创建、配置和管理 bean 的方式。
- Spring 框架的功能可以用在任何 J2EE 服务器中,大多数功能也适用于不受管理的环境。Spring 的核心要点是:支持不绑定到特定 J2EE 服务的可重用业务和数据访问对象。毫无疑问,这样的对象可以在不同 J2EE 环境 (Web 或 EJB)、独立应用程序、测试环境之间重用。
SpringBoot和SpringCloud
- Spring Boot :一款可以快速构建Spring应用的脚手架; 约定大于配置 , 承上启下。
- Spring Cloud:基于SpringBoot实现的;他是一个生态圈;
2. spring官网及下载地址
- Spring官网:https://spring.io/
- Spring下载:https://spring.io/projects/spring-framework#learn
- SpringGithub地址:https://github.com/spring-projects/spring-framework
- Spring官网下载地址:https://repo.spring.io/release/org/springframework/spring/
3. IOC
1. IOC本质
控制反转 (inversion of Control):IOC
IOC是一种设计思想,这个思想的实现方式是DI:依赖注入。
IOC的本质是设置接口,是一种抽象思维。
反转:从编写代码到编写接口,程序具有了高配置性和动态性,使得程序的耦合性大幅降低。
2. IOC推导
IOC的目的是解决企业应用开发的复杂性。它使用基本的JavaBean代替EJB,并提供了更多的企业应用功能。适用于任何任何Java应用。
hello Spring
-
导jar包
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>4.3.9.RELEASE</version> </dependency>
-
创实体类
package com.david.pojo; public class Hello { private String name; public Hello() { } public Hello(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } public void show(){ System.out.println("Hello,"+name); } @Override public String toString() { return "Hello{" + "name='" + name + '\'' + '}'; } }
-
编写Spring的配置文件:beans.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就是一个java对象,由Spring管理和创建--> <bean id="hello" class="com.david.pojo.Hello"> <property name="name" value="Spring"/> </bean> <bean id="hello2" class="com.david.pojo.Hello"> <property name="name" value="WestOS"/> </bean> </beans>
-
测试
package com.david.pojo; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class HelloTest { @Test public void test(){ //解析beans.xml配置文件,生产管理相应的Bean对象; ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); //通过Bean得到这个对象的实体 Hello hello = (Hello)context.getBean("hello2"); hello.show(); } }
-
注意:
- DI ,本质就是利用set方式来注入的;
- IOC是一种编程思想。由主动的编程到被动的接受;
- 程序本身不创建对象了,变成被动接受Spring创建的对象;
- 不再在程序中去改动代码 , 要实现不同的操作 , 只需要在xml配置文件中进行修改 , 所谓的IoC,一句话搞定 : 对象由Spring 来创建 , 管理 , 装配 !
-
IOC创建对象的方式:
-
beans.xml
<?xml version="1.0" encoding="UTF-8"?> <!--suppress SpringFacetInspection --> <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="UserDaoImpl" class="com.david.dao.UserDaoImpl"/> <bean id="UserDaoMysqlImpl" class="com.david.dao.UserDaoMysqlImpl"/> <bean id="UserDaoOracleDao" class="com.david.dao.UserDaoOracleDao"/> <bean id="ServiceImpl" class="com.david.service.UserServiceImpl"> <!--普通的值使用value,引用其他bean使用ref--> <property name="userDao" ref="UserDaoMysqlImpl"/> </bean> </beans>
-
SpringTest
package com.david.test; import com.david.service.UserServiceImpl; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class SpringTest { @Test public void test(){ ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); UserServiceImpl userService = (UserServiceImpl) context.getBean("ServiceImpl"); userService.getUser(); } }
-
-
IOC创建对象的方式
我们平时创建对象的方式:有参构造 、无参构造
-
创建实体类
package com.david.pojo; public class User { private String name; private String sex; private int age; public User() { System.out.println("User的无参构造"); } public User(String name) { System.out.println("User的有参构造"); this.name = name; } public User(String name, int age) { System.out.println("User的有参构造2"); this.name = name; this.age = age; } public User(String name, String sex, int age) { System.out.println("User的有参构造3"); this.name = name; this.sex = sex; this.age = age; } public void setName(String name) { System.out.println(name+":"+System.currentTimeMillis()); this.name = name; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "User{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
-
Spring配置文件
<?xml version="1.0" encoding="UTF-8"?> <!--suppress SpringFacetInspection --> <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"> <!-- Spring的配置文件 bean 代表一个对象 alias 别名 import 导入一个其他资源 --> <bean id="user" class="com.david.pojo.User"> <property name="name" value="stark"/> </bean> <!--使用构造器的参数下标进行赋值--> <bean id="user2" class="com.david.pojo.User"> <constructor-arg index="0" value="tony"/> <constructor-arg index="1" value="18"/> </bean> <!--通过名字进行赋值--> <bean id="user3" class="com.david.pojo.User"> <constructor-arg name="name" value="iron man"/> <constructor-arg name="age" value="3"/> </bean> <!--通过类型进行赋值--> <bean id="user4" class="com.david.pojo.User"> <constructor-arg type="java.lang.String" value="david"/> <constructor-arg type="java.lang.Integer" value="18"/> <constructor-arg type="java.lang.String" value="男"/> </bean> </beans>
-
测试类
package com.david.pojo; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class UserTest { @Test public void test(){ ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); User user = (User)context.getBean("user"); System.out.println(user.toString()); } @Test public void test2(){ ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); User user = (User) context.getBean("user4"); System.out.println(user); } }
-
小结:
-
通过有参构造
- 通过下标
- 通过参数名 【推荐】
- 通过参数类型
-
通过无参构造
默认会用无参构造
一定要有一个无参构造方法
-
-
4. Spring配置文件
-
beans:
-
没有id,没有name,我们依旧可以获取这个对象,但是不建议使用、需要使用类的class对象获取;
User bean = context.getBean(User.class);
-
id 就是对象的名字
-
class 就是要实例化的类
-
name就是别名
有id的时候,name是别名 , 没有id的时候,name就是对象的名字;别名可以起多个。
-
-
alias
-
name : 就是bean对象的id
-
alias : 对象的别名
-
<alias name="user" alias="user01"/>
-
-
import
-
作用:导入另外一个资源,把另外配置文件装进来
-
classpath: 只会在classpath中寻找文件,找不到就报错;
import一般在团队项目中会使用,每个人开发各自的beans.xml,最后用一个总的文件拼装起来。
-
5. 依赖注入DI
依赖注入:DI (Dependency Injection)
- 依赖:指bean对象的创建依赖于Spring容器。bean对象依赖的资源
- 注入:指Bean对象所依赖的资源,由容器来设置和装配。
构造器注入:
- 有参
- 无参
setter注入:
-
要求被注入的属性,必须有set方法。set方法的名字需要规范
set+属性名(属性名字母大写)
1. 常量注入
<!--普通字段-->
<porperty name = "name" value = "啊侠"/>
2. BEAN注入
<!--引用其他bean使用热风ref-->
<property name = "adderss" ref = "addr"/>
3. 数组引入
<!--数组注入-->
<property name = ""books>
<array>
<value>七龙珠</value>
<value>圣斗士</value>
<value>名侦探柯南</value>
<value>海贼王</value>
</array>
</property>
4. list注入
<!--List注入-->
<property name="hobbys">
<list>
<value>恋爱</value>
<value>运动</value>
<value>电影</value>
<value>音乐</value>
</list>
</property>
5. map注入
标签:entry
键:使用key
值: 使用value
<!--Map的注入-->
<property name="card">
<map>
<entry key="IdentificationCard" value="666666888888884444"/>
<entry key="CreditCard" value="111122223333444"/>
</map>
</property>
6. set注入
<!--Set注入-->
<property name="games">
<set>
<value>和平精英</value>
<value>刺激战场</value>
<value>绝地求生</value>
<value>穿越火线</value>
</set>
</property>
7. 空值注入
<!--null标签空值注入-->
<property name = "friends">
<null/>
<property/>
8. property注入
props标签,使用key属性,值在标签中间。
<!--Properties注入-->
<property name="info">
<props>
<prop key="学号">2016060215</prop>
<prop key="性别">male</prop>
<prop key="姓名">ironMan</prop>
</props>
</property>
9.扩展知识:p命名空间注入和c命名空间注入
-
p命名空间(属性注入)
<!--需要导入对应的约束文件--> <!--p:property属性,命名空间注入--> <bean id="user1" class="com.kuang.pojo.User" p:name="狂神" p:age="18"/>
-
c命名空间注入(构造器注入)
<!--c:constructor构造器:命名空间注入--> <bean id="user2" class="com.kuang.pojo.User" c:name="狂神" c:age="19"/>
Spring就是一个粘合剂,托管所有的对象
6. bean作用域及自动安装
bean就是由IOC容器初始化、装配及管理的对象
配置文件中定义 Bean 时,我们可以配置 Bean 的属性值以及相互之间的依赖关系,还可以定义 Bean 的作用域 。作用域会对 Bean 的生命周期和创建方式产生影响 。
bean的作用域类型
类型 | 说明 |
---|---|
singleton | 在 Spring 容器中仅存在一个 Bean 实例, Bean 以单例的形式存在,默认值。 |
prototype | 每次从容器中调用 Bean 时,都会返回一个新的实例,即相当于执行 new XxxBean() 的实例化操作。 |
request | 每次 http 请求都会创建一个新的 Bean , 仅用于 WebApplicationContext 环境。request.setAttribute("","") |
session | 同一个 http Session 共享一个 Bean ,不同的 http Session 使用不同的 Bean,仅用于 WebApplicationContext 环境。session.setAttribute("","") |
globalSession | 同一个全局 Session 共享一个 bean, 用于 Porlet, 仅用于 WebApplication 环境。application.setAttribute("","") |
Spring 以容器的方式,使得我们仅需配置,即可得到天然的单例模式。
在以上的作用域中,request、session和globalSession三种作用域仅在web的应用中使用。