spring
1.简介:
spring:春天---->给软件行业带来了春天
2002.首次推出了spring框架的雏形,interface21框架。
spring框架即以interface21框架为基础,经过重新设计,并不断丰富内涵,于2004年3.24正式发布。
Rod Johnsop : spring Framework的创始人,著名作者,悉尼人,专业不是计算机而是是音乐学
spring理念:简化企业级开发。 使用现有的技术更加容易使用,本身是一个大杂烩,整合了现有的技术。
SSH:Struct2+Spring+Hibernate
SSM:Spring+SpringMVC+SpringMyBatis
官方下载地址:
1.2优点:
spring是一个开源的免费的框架。
spring是一个轻量级的,非入侵式的框架。
轻量级:本身很小,下载包(jar包)就可以使用。
非入侵的:引入包对里原来的项目没有任何影响,反而会更加简单。
入侵的:引入包会对原来的项目工程会产生影响。
控制反转(IOC):
依赖注入(DI):
面向切面编程(AOP):
支持事务处理,对框架整合的支持。
总结:Spring是一个轻量级,非入侵的控制反转(IOC)和面向切面编程(AOP)的框架。
spring模块:七大模块。
拓展:
![](https://img-blog.csdnimg.cn/20210617092915891.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzUyNjMyMTUw,size_16,color_FFFFFF,t_70)
IOC理论推导
1.userdao接口
2.userdaoimpl实现类
3.userservice业务接口
4..userserviceimpl业务实现类。
使用IDEA:
创建项目:
导入架包:
![](https://img-blog.csdnimg.cn/20210617093233624.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzUyNjMyMTUw,size_16,color_FFFFFF,t_70)
每一次因为用户的请求,写代码的人要改大量的代码,要增加类,还要改代码。 手代动改原有的代码,假设十几万行代码,每一次因为用户不同的需求,程序员就要改代码。 private UserDao userdao = new UserDaoMysqlImpl();//写死的 能不能让上面代码不动,用户 在我们之前的业务中,用户的需求可能会影响我们原来的代码,我们需要根据用户的需求去修改源代码, 如果代码量十分大,修改一次的成本代价十分贵 我们使用一个set接口的实现。已经发生了革命性的变化 //利用set进行动态实现值的注入。 接口的实现。 public void setUserDao(UserDao userDao) { this.userdao = userdao; } 之前,程序是主动创建对象,控制权在程序员手上 使用set注入后,程序不在具有主动性,而是变成被动接受的对象 这种思想从本质上解决了问题,我们程序元不在去管理对象的创建,系统耦合性大大降低,可以更加专注的在业务实现上。这是IOC的反转主动权在用户 控制反转
接口是纯粹的抽象类,接口在所有的方法都是抽象的(只有声明,没有定义) //2.子类实现 接口用implement关键字 继承 抽象类用extends关键字 //3.子类可以实现多个接口,但只能继承一个抽象类 //4.一个子类如果实现了一个接口,就必须重写这个接口里所有的方法 //抽象类的子类可以不重写抽象父类里的所有方法,但这个子类会自然称为抽象类
接口的最主要的作用是达到统一访问,就是在创建对象的时候用接口创建,
接口名 对象 = new 实现接口的类
这样你想用哪个类的对象,就可以new 哪个对象了,不需要改原来的代码,就和USB接口一样,插什么读什么,就是这个原理
具体的步骤:
-
先创建工程
-
生成pom.xml文件
-
在pom.xml文件中导入jar包
<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.2.0.RELEASE</version> </dependency> </dependencies>
导入成功。
4.创建UserDao接口
package cn.tedu.dao; //1.传统的接口类 userdao 接口是纯粹的抽象类,接口在所有的方法都是抽象的(只有声明,没有定义) //2.子类实现 接口用implement关键字 继承 抽象类用extends关键字 //3.子类可以实现多个接口,但只能继承一个抽象类 //4.一个子类如果实现了一个接口,就必须重写这个接口里所有的方法 //抽象类的子类可以不重写抽象父类里的所有方法,但这个子类会自然称为抽象类 //先写一个接口类 public interface UserDao { void getUser();//定义抽象方法 }
5.创建UserDaoImpl实现类
//实现类 //impl实现这个接口类 public class UserDaoImpl implements UserDao{ @Override(重写这个接口的所有方法) public void getUser() { //输出的快捷键 直接打sout 回车 就直接输出输出语句。 System.out.println("默认获取用户的数据。"); } }
6.创建UserService业务接口
package cn.tedu.service1; //该类是业务层的接口类 public interface UserService1 { public void getUser(); }
7.创建UserServiceImpl业务实现:
里面就做了业务层调用数据层
//业务层的实现类 public class UserServiceImpl1 implements UserService1{ //业务层调用数据层 通过new 把数据层拿过来 private UserDao1 userdao1 = new UserDaoImpl1();程序控制对象,写死的 @Override public void getUser() { userdao1.getUser(); }
8.测试类
public class Test1 { //这想到与servlet调真实的业务 //用户实际调用的是业务层,dao层不需要接触 public static void main(String[] args) { new业务层的对象 拿到业务层 UserService1 userservice1 = new UserServiceImpl1(); 调用业务层的方法 userservice1.getUser(); } }
重点来了,我们增加需求,增加mysql的实现
1.这时需要增加UserDaoMysqlIpml实现类:
UserDaoMysqlImpl1增加的实现类 public class UserDaoMysqlImpl1 implements UserDao1{ //UserDaoMysqlImpl实现类 @Override public void getUser() { System.out.println("mysql获取用户数据"); } }
2.该怎么调用呢?????
我们需要在业务层的实现类UserServiceImpl 重新调用 这就需要把 UserDaoImpl 该成 UserDaoMysqlImpl
//业务层的实现类 public class UserServiceImpl1 implements UserService1{ //业务层调用数据层 通过new 拿过来 private UserDao1 userdao1 = new UserDaoMysqlImpl1(); @Override public void getUser() { } //子类实现接口,就必须实现这个接口的所有方法 //服务层调用Dao层
3.测试结果:
这样做的弊端:要增加类,还要改代码。代码要根据用户的需求来变,每次该代码成本都很高
如何解决这个问题,就是既满足用户的需求,又不会去改代码,这就用到了控制反转(IOC)的思想。 从由程序员控制代码转向由用户自己控制。
1.使用Set方法 实现动态值的注入
//利用set进行动态实现值的注入。 接口的实现。 public void setUserDao(UserDao userDao) { this.userdao = userdao; }
((UserServiceImpl) userservice1).setUserdao1(new UserDaoMysqlImpl());
IOC:IOC是spring框架的核心内容
使用多种方式完美的实现了Ioc,可以使用xml文件也可以使用注解,新版本的Spring也可以实现零配置
spring容器在初始化时先读取配置文件,根据配置文件或元数据创建于组织对象存入容器中,程序使用时在从IOC容器中取出需要的对象。
控制反转是通过描述(XML或注解)并通过第三方去生产获知获取特定对象的方式。在Spring容器中实现控制反转的是ioc容器,其实现方式是依赖注入(DI)
HelloSpring
1.先创建一个普通的Hello实体类:
package cn.tedu.pojo; import javax.swing.*; //很简单的实体类 就一个Str public class Hello { private Spring str; //生成get set 方法 使用快捷键 Alt+insert public Spring getStr() { return str; } public void setStr(Spring str) { this.str = str; } @Override public String toString() { return "Hello{" + "str=" + str + '}'; } }
2.在resources下创建一个文件,原始名字叫ApplicationContext.xml 为了方便 起名 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 https://www.springframework.org/schema/beans/spring-beans.xsd"> <!--使用Spring来创建对象,在Spring这些都称为bean 类型 变量名 = new 类型(); bean = 对象 new Hello(); id= 变量名 class=全路径 new的对象 property 想当于给对象中的属性设置值。 --> <bean id="Hello" class="cn.tedu.pojo.Hello"> <property name="str" value="Spring"/> </bean> </beans>
3.写测试类
public class MyTest { public static <hello> void main(String[] args) { //new ClassPathXmlApplicationContext:固定的 //获取SPringle的上下文对象 //获取容器 写法是固定的 ApplicationContext context = new ClassPathXmlApplicationContext("beas.xml"); //我们的对象都在SPring中管理了,我们要使用,直接去里面取出来就可以了 hello Hello = (hello) context.getBean("Hello"); System.out.println(Hello.toString()); } }
1.Hello对象是谁创建的?
答:Hello对象是由Spring创建的
2.Hello对象的属性是怎么设置的?
答:对象的属性是由Spring容器设置的
这个过程叫控制反转:
控制:谁来控制对象的创建,传统应用程序的对象是由程序本身控制创建的,使用Spring后,对象是由Spring来创建的。
反转:程序本身不创建对象,而变成被动的接受对象。
依赖注入: 就是利用set方法进行注入。
IOC是一种编程思想,由主动的编程转变成被动的接收。
所谓的IOC就是一句话: 对象是由Spring 来创建,管理,装配!
IOC
Spring配置:
5.1 别名 alias
5.2:bean的配置(重点)
<bean id="Hello" class="cn.tedu.pojo.Hello" name="">
id: bean的唯一标识符,也就是相当于我们学的对象名。 一般跟类名同名。
class:bean对象所对应的类型:包名+类名
name:也是别名,可以同时取多个
5.3import:
这个import,一般用于团队开发使用,它可以将多个配置文件,导入合并为一个假设,可以用import 将所有的beans.xml合并为一个总的。
DI依赖注入。
1.构造器
2.set方式注入(重点)
3.其它(拓展)方式注入
环境搭建:
1.复杂类型(引用数据类型)
public class Address { private String address;//引用数据类型 public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } }
2。真实测试对象
public class Student { private String name; private Address address; private String[] books; private List<String> hobby; private Map<String,String> card; private Set<String> wife; private Properties info;
3.beans.xml
<!--使用Spring来创建对象,在SPringle这些都称为bean 类型 变量名 = new 类型(); bean = 对象 new Hello(); id= 变量名 class=全路径 new的对象 property 想当于给对象中的属性设置值。 value:数据类型。 --> <bean id="student" class="cn.tedu.pojo.Student"> <!--第一种,普通值的注入 value set注入--> <property name="name" value="小杨"/> </bean> </beans>
4.测试类:
public class MyTest { public static void main(String[] args) { //获取容器 ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); Student student = (Student) context.getBean("student"); System.out.println(student.getName()); } }
完善注入信息
<bean id="address" class="cn.tedu.pojo.Address"> <property name="address" value="西安"/> </bean> <bean id="student" class="cn.tedu.pojo.Student"> <!--第一种,普通值的注入 value set注入--> <property name="name" value="小杨"/> <!--第二种:Bean 注入,ref 引用数据类型--> <property name="address" ref="address"/> <!--数组注入,array--> <property name="books"> <array> <value>数学分析</value> <value>高等代数</value> <value>解析几何</value> </array> </property> <!--List注入:--> <property name="hobby"> <list> <value>sing</value> <value>movies</value> <value>敲代码</value> </list> </property> <!--Map集合注入--> <property name="card"> <map> <entry key="身份证" value="1122334" /> <entry key="银行卡" value="233455" /> </map> </property> <!--Set--> <property name="wife"> <set> <value>LOL</value> <value>COC</value> <value>BOB</value> </set> </property> <!--properties null--> <property name="info"> <null></null> </property> </bean>
5.拓展方式注入
我们可以使用p命名空间,和c命名空间进行注入,官方解释
代码:
<!--p命名空间注入,可以直接注入属性的值:property--> <bean id="user" class="cn.tedu.pojo.User" p:name="xiaoy" p:age="18"/> <!--c命名空间注入,通过构造器 construte--> <bean id="user1" class="cn.tedu.pojo.User" c:name="小杨" c:age="18
测试:
@Test public void test2(){ ApplicationContext context = new ClassPathXmlApplicationContext("UserBean.xml"); User user = (User) context.getBean("user1"); System.out.println(user);
注意点:
注意点:p命名和c命名空间不能直接使用,需要导入xml约束:
xmlns:c="http://www.springframeork.org/schema/c"
xmlns:p="http://www.springframeork.org/schema/c"
6.bean的作用域。 bean Scops
![](https://img-blog.csdnimg.cn/20210617092812383.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzUyNjMyMTUw,size_16,color_FFFFFF,t_70)
当你创建bean时候你可以指定作用域。
singleton
1.代理模式(spring默认机制)
<bean id ="user2" class="cn.tedu.pojo.Usre c:age="18" c:name="xiaoy " scopr="singleton"
2.原型模式:每次从容器中get的时候,都会产生一个新对象
<bean id ="user2" class="cn.tedu.pojo.Usre c:age="18" c:name="xiaoy " scopr="prototye"
3.其余的request(请求创建完失效),session(一直在session中活着),application(全局都活着).这些个在web开发中使用