简介
Spring框架是由于软件开发的复杂性而创建的。Spring使用的是基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅仅限于服务器端的开发。从简单性、可测试性和松耦合性角度而言,绝大部分Java应用都可以从Spring中受益。
- 目的:解决企业应用开发的复杂性
- 功能:使用基本的JavaBean代替EJB,并提供了更多的企业应用功能
- 范围:任何Java应用
Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架。
优点
- 非侵入式设计
Spring是一种非侵入式(non-invasive)框架,它可以使应用程序代码对框架的依赖最小化。- 方便解耦、简化开发
Spring就是一个大工厂,可以将所有对象的创建和依赖关系的维护工作都交给Spring容器的管理,大大的降低了组件之间的耦合性。- 支持AOP
Spring提供了对AOP的支持,它允许将一些通用任务,如安全、事物、日志等进行集中式处理,从而提高了程序的复用性。- 支持声明式事务处理
只需要通过配置就可以完成对事物的管理,而无须手动编程。- 方便程序的测试
Spring提供了对Junit4的支持,可以通过注解方便的测试Spring程序。- 方便集成各种优秀框架
Spring不排斥各种优秀的开源框架,其内部提供了对各种优秀框架(如Struts、Hibernate、MyBatis、Quartz等)的直接支持。- 降低Jave EE API的使用难度。
Spring对Java EE开发中非常难用的一些API(如JDBC、JavaMail等),都提供了封装,使这些API应用难度大大降低。
组成
Spring框架的7个模块:
IOC理论推导
IOC(DI)-控制反转(依赖注入)
spring ioc指的是控制反转,IOC容器负责实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。交由Spring容器统一进行管理,从而实现松耦合。
而在创建对象的过程中Spring可以依据配置对象的属性进行设置,这个过程称之为依赖注入,也即DI
在我们之前的业务中,对象都需要程序猿自己主动new出来,用户的需求可能会影响我们原来的代码,我们需要根据用户的需求去修改原代码!如果程序代码量十分大,修改一次的成本代价十分昂贵!
1、UserDao 接口
2、UserDaoImpl 实现类
3、UserService 业务接口
private UserDao userDao = new UserDaoImpl();
4、UserServiceImpl 业务实现类
现在通过Set接口实现
private UserDao userDao;
//利用set进行动态实现值的注入
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
之前,程序是主动创建对象,控制权在程序猿手上,使用Set注入后,程序不再具有主动性,而是变成了被动的接受对象
这种思想,从本质上解决了问题,程序猿不需要再去管理对象的创建了.系统的耦合性大大降低,可以更加专注于业务的实现上,这就是IOC的原型
IOC本质
控制反转IoC(Inversion of Control),是一种设计思想,DI(依赖注入)是实现IoC的一种方法。没有IoC的程序中 , 我们使用面向对象编程 , 对象的创建与对象间的依赖关系完全硬编码在程序中,对象的创建由程序自己控制,控制反转后将对象的创建转移给第三方,所谓控制反转就是:获得依赖对象的方式反转了。
HelloSpring
依赖注入 : 就是利用set方法来进行注入的.
IOC是一种编程思想,由主动的编程变成被动的接收
导入依赖 pom.xml 网址
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.3</version>
</dependency>
实体类:
public class Hello {
private String str;
public String getStr() {
return str;
}
public void setStr(String str) {
this.str = str;
}
@Override
public String toString() {
return "Hello" + " " + str;
}
}
配置文件
<?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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="hello" class="cn.pinked.pojo.Hello">
<property name="str" value="spring"/>
</bean>
</beans>
测试
@Test
public void hellotest(){
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
Hello hello = (Hello) context.getBean("hello");
System.out.println(hello.toString());
}
我们不用再程序中去改动了 , 要实现不同的操作 , 只需要在xml配置文件中进行修改 , 所谓的IoC,一句话搞定 : 对象由Spring 来创建 , 管理 , 装配
IOC创建对象的方式
Spring创建对象的方式:在配置文件加载的时候,容器中管理的对象就已经初始化了
-
通过有参构造
- 通过下标
<bean id="user" class="com.kuang.pojo.User"> <constructor-arg index="0" value="张三"/> </bean>
- 通过参数名 【推荐】
<bean id="user" class="com.kuang.pojo.User"> <constructor-arg name="name" value="张三"/> </bean>
- 通过参数类型
<bean id="user" class="com.kuang.pojo.User"> <constructor-arg type="java.lang.String" value="李四"/> </bean>
-
通过无参构造
- 默认会用无参构造
<bean id="user" class="com.kuang.pojo.User"> <property name="name" value="张三"/> </bean>
注意点:实体类中一定要有一个无参构造方法
Spring配置
- alias 别名
<alias name="user" alias="userrrrrr"/>
- bean的配置
id: bean的唯一标识符,相当于对象名
class: bean对象所对应的全限定名-包名+类型
name:别名,可以有多个别名
<bean id="userT" class="cn.pinked.pojo.UserT" name="userT2 userT3,userT4"></bean>
3.import
用于导入配置文件
<import resource="beans.xml"/>
<import resource="beans2.xml"/>
<import resource="beans3.xml"/>
依赖注入
- 导入相关依赖
<!-- spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.25.RELEASE</version>
</dependency>
- 添加配置文件
在src中书写配置,注册对象到容器,书写xml文件,applicationContext.xml放在src下(这个文件的本身位置是任意的,名字也是任意的,只是建议这样书写)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd ">
<bean name="user" class="cn.itcast.bean.User" ></bean>
</beans>
- 使用注入
通常的javabean属性都会私有化,而对外暴露setXxx()getXxx()方法,此时spring可以通过这样的setXxx()方法将属性的值注入对象。
(1)set注入
依赖:bean对象的创建依赖于容器
注入:bean对象中的所有属性,由容器来注入
service
private UserDaoImpl userDaoImpl;
public void setUserDaoImpl(UserDaoImpl userDaoImpl){
this.userDaoImpl = userDaoImpl;
}
修改配置文件:
<bean name="u" class="你需要注入的那个类"></bean>
<bean name="userService" class="要创建对象的那个类">
<property name="userDao" ref="u"></property> //name 必须和userService 对应类里面的 属性名称一模一样
</bean>
<!-- index:为构造方法的第几个参数 进行配置
name:为构造方法的哪个名字的参数进行配置
**index 和 name 可以配置任何一个或同时配置 但要求一旦配置必须正确
**推荐优先使用index方式配置 防止没有源码造成name无法匹配到对应参数
type:该构造方法参数的类型
value:该构造方法参数的值 ,用来指定基本值
ref:该构造方法参数的值,用来指定引用其他bean的值
-->
(2)构造方法注入
对象属性设置的另一种方式是在对象的过程中通过构造方法传入并设置对象的属性。spring也可以通过这样的构造方法实现属性的注入。
service
private UserDaoImpl userDaoImpl;
public void setUserDaoImpl(UserDaoImpl userDaoImpl){
this.userDaoImpl = userDaoImpl;
}
public UserServiceImpl(UserDaoImpl userDaoImpl,Integer age,String name) {
this.userDaoImpl = userDaoImpl;
System.out.println("age:" + age);
System.out.println("a:" + name);
}
修改配置文件:
<bean name="userDao" class="你需要注入的那个类"></bean>
<bean name="userService"
class="com.hxzy.lkw.service.impl.UserServiceImpl">
<constructor-arg>
<ref bean="userDao" />
</constructor-arg>
<constructor-arg type="java.lang.Integer" value="55"></constructor-arg>
<constructor-arg type="java.lang.String" value="abcd"></constructor-arg>
</bean>
(3) 接口注入
service
private UserDao userDao; //接口
public void setUserDaoImpl(UserDao userDao){
this.userDao = userDao;
}
修改配置文件:
<bean name="u" class="你需要注入的那个类"></bean>
<bean name="userService" class="要创建对象的那个类">
<property name="userDao" ref="u"></property> //name 必须和userService 对应类里面的 属性名称一模一样
</bean>
( 4)自动装配
在Spring的set方式实现的注入过程中,支持自动装配机制,所谓自动装配机制,会根据要设置的javabean属性的名字 或 类型 到spring中自动寻找对应id 或 类型的进行设置,从而 省去依次配置的过程,简化了配置。
修改配置文件:
<?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-3.2.xsd"
>
<!--autowire设定自动装配:
byName:根据javabean中需要注入的属性的名字 ,在spring容器中找对应id的<bean>将该<bean>的对象复制给 当前的属性
byType:根据javabean中需要注入的属性的类型,在spring容器中找对应class类型的<bean>将该<bean>的对象复制给 当前的属性
**byType方式 根据类型进行匹配,可能匹配到多个<bean>,此时会抛出异常。而byName是通过id来寻找<bean>,id没有重复,不会有这方面的问题,所以推荐使用byName方式
-->
<bean id="teacher" class="cn.tedu.beans.Teacher" autowire="byName"></bean>
<bean id="dog" class="cn.tedu.beans.Dog"></bean>
<bean id="cat" class="cn.tedu.beans.Cat"></bean>
</beans>
bean的作用域
1、单例模式(默认)
<bean id="user" class="cn.pinked.pojo.User" p:name="大头儿子" p:age="6" scope="singleton"/>
2、原型模式:每次从容器中get的时候,都会产生一个新对象
<bean id="user" class="cn.pinked.pojo.User" p:name="大头儿子" p:age="6" scope="prototype"/>
3、其余的作用于web的生命周期中