当前位置: 首页 > news >正文

上海网站建站多少钱厦门海沧建设局网站

上海网站建站多少钱,厦门海沧建设局网站,淘客优惠券网站建设,wordpress grace8前置知识#xff1a; 掌握Java基础知识#xff08;特别是反射#xff09;掌握Java注解掌握XML掌握Maven Spring5学习笔记 1、Spring概述1.1、简介1.2、优点1.3、组成1.4、拓展 2、IOC理论推导2.1、分析实现2.2、IOC本质 3、HelloSpring3.1、导入jar包3.2、编写代码3.3、思考…前置知识 掌握Java基础知识特别是反射掌握Java注解掌握XML掌握Maven Spring5学习笔记 1、Spring概述1.1、简介1.2、优点1.3、组成1.4、拓展 2、IOC理论推导2.1、分析实现2.2、IOC本质 3、HelloSpring3.1、导入jar包3.2、编写代码3.3、思考3.4、修改案例一 4、IOC创建对象的方式4.1、使用无参构造创建对象默认4.2、使用有参构造创建对象 5、Spring配置5.1、别名5.2、Bean的配置5.3、import 6、依赖注入6.1、构造器注入6.2、Set方式注入【重点】6.3、拓展方式注入6.4、Bean的作用域 7、Bean的自动装配7.1、测试7.2、ByName自动装配7.3、ByType自动装配7.4、使用注解实现自动装配 8、使用注解开发8.1、说明8.2、Bean的实现 9、使用Java的方式配置Spring10、代理模式10.1、静态代理10.2、静态代理的好处10.3、加深理解静态代理10.4、动态代理 11、AOP11.1、什么是AOP11.2、AOP在Spring中的作用11.3、使用Spring 实现AOP 12、整合Mybatis12.1、回忆Mybatis12.2、****MyBatis-Spring学习****12.3、整合实现一12.4、整合实现二 13、声明式事务13.1、回顾事务13.2、测试13.3、Spring中的事务管理 总结 1、Spring概述 1.1、简介 简化企业开发的复杂性 Spring理念使现有的技术更加容易使用本身是一个大杂烩整合了现有的技术框架。 SSHStruct2 Spring HibernateSSMSpring MVC Spring MyBatis 官网 : http://spring.io/ 官方下载地址 : https://repo.spring.io/libs-release-local/org/springframework/spring/ GitHub : https://github.com/spring-projects 1.2、优点 Spring是一个开源的免费的框架集合Spring是一个轻量级的、非入侵式的框架控制反转IoC、面向切面编程AOP支持事务的处理对框架整合的支持 总结一句话Spring就是一个轻量级的控制反转IoC和面向切面编程AOP的框架。 1.3、组成 Spring 框架是一个分层架构由 7 个定义良好的模块组成。Spring 模块构建在核心容器之上核心容器定义了创建、配置和管理 bean 的方式。 组成 Spring 框架的每个模块或组件都可以单独存在或者与其他一个或多个模块联合实现。每个模块的功能如下 核心容器核心容器提供 Spring 框架的基本功能。核心容器的主要组件是 BeanFactory它是工厂模式的实现。BeanFactory 使用控制反转IOC 模式将应用程序的配置和依赖性规范与实际的应用程序代码分开。Spring 上下文Spring 上下文是一个配置文件向 Spring 框架提供上下文信息。Spring 上下文包括企业服务例如 JNDI、EJB、电子邮件、国际化、校验和调度功能。Spring AOP通过配置管理特性Spring AOP 模块直接将面向切面的编程功能 , 集成到了 Spring 框架中。所以可以很容易地使 Spring 框架管理任何支持 AOP的对象。Spring AOP 模块为基于 Spring 的应用程序中的对象提供了事务管理服务。通过使用 Spring AOP不用依赖组件就可以将声明性事务管理集成到应用程序中。Spring DAOJDBC DAO 抽象层提供了有意义的异常层次结构可用该结构来管理异常处理和不同数据库供应商抛出的错误消息。异常层次结构简化了错误处理并且极大地降低了需要编写的异常代码数量例如打开和关闭连接。Spring DAO 的面向 JDBC 的异常遵从通用的 DAO 异常层次结构。Spring ORMSpring 框架插入了若干个 ORM 框架从而提供了 ORM 的对象关系工具其中包括 JDO、Hibernate 和 iBatis SQL Map。所有这些都遵从 Spring 的通用事务和 DAO 异常层次结构。Spring Web 模块Web 上下文模块建立在应用程序上下文模块之上为基于 Web 的应用程序提供了上下文。所以Spring 框架支持与 Jakarta Struts 的集成。Web 模块还简化了处理多部分请求以及将请求参数绑定到域对象的工作。Spring MVC 框架MVC 框架是一个全功能的构建 Web 应用程序的 MVC 实现。通过策略接口MVC 框架变成为高度可配置的MVC 容纳了大量视图技术其中包括 JSP、Velocity、Tiles、iText 和 POI。 1.4、拓展 现代化的Java开发说白就是基于Spring的开发。 Spring Boot 一个快速开发的脚手架基于SpringBoot可以快速开发单个微服务约定大于配置 Spring Cloud SpringCloud是基于SpringBoot实现的 因为现在大多数公司都在使用SpringBoot进行快速开发学习SpringBoot的前提需要完全掌握Spring及SpringMVC。 承上启下的作用。 弊端发展了太久之后违背了原来的理念。配置十分繁琐人称“配置地狱”。 2、IOC理论推导 2.1、分析实现 UserDao接口UserDaolmpl实现类UserService业务接口UserService业务实现类 在我们之前的业务中用户的需求可能会影响我们原来的代码我们需要根据用户的需求去修改原代码。如果程序代码量十分大修改一次的成本代价十分昂贵 我们使用一个Set接口实现已经发生了革命性的变化。 private UserDao userDao;//set方法利用set进行动态实现值的注入public void setUserDao(UserDao userDao) {this.userDao userDao;}之前程序是主动创建对象控制权在程序猿手上。 使用了set注入后程序不再具有主动性而是变成了被动的接受对象。 这种思想从本质上解决了问题我们程序猿不用再去管理对象的创建。系统的耦合性大大降低可以更加专注的在业务的实现上。这是IOC的原型。 2.2、IOC本质 原本主动权在业务层在程序猿手上set注入后主动权在用户手上实现了控制反转。 控制反转IoC(Inversion of Control)是一种设计思想DI(依赖注入)是实现IoC的一种方法也有人认为DI只是IoC的另一种说法。没有IoC的程序中 , 我们使用面向对象编程 , 对象的创建与对象间的依赖关系完全硬编码在程序中对象的创建由程序自己控制控制反转后将对象的创建转移给第三方个人认为所谓控制反转就是获得依赖对象的方式反转了。 IoC是Spring框架的核心内容使用多种方式完美的实现了IoC可以使用XML配置也可以使用注解新版本的Spring也可以零配置实现IoC。 采用XML方式配置Bean的时候Bean的定义信息是和实现分离的而采用注解的方式可以把两者合为一体Bean的定义信息直接以注解的形式定义在实现类中从而达到了零配置的目的。 控制反转是一种通过描述XML或注解并通过第三方去生产或获取特定对象的方式。在Spring中实现控制反转的是IoC容器其实现方法是依赖注入Dependency Injection,DI。 3、HelloSpring 3.1、导入jar包 注 : spring 需要导入commons-logging进行日志记录 . 我们利用maven , 他会自动下载对应的依赖项 dependencygroupIdorg.springframework/groupIdartifactIdspring-webmvc/artifactIdversion5.1.10.RELEASE/version /dependency3.2、编写代码 编写一个Hello实体类 public class Hello {private String name;public String getName() {return name;}public void setName(String name) {this.name name;}public void show(){System.out.println(Hello, name );} }编写我们的spring文件 , 这里我们命名为beans.xml ?xml version1.0 encodingUTF-8? beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://www.springframework.org/schema/beanshttps://www.springframework.org/schema/beans/spring-beans.xsd!--使用Spring来创建对象在Spring这些都称为Bean类型 变量名 new 类型();Hello hello new Hello();id 变量名;class new 的对象;property 相当于给对象中的属性设置一个值--!--使用Spring来创建对象在Spring中这些都称为Bean--bean id hello class com.shelly.pojo.Helloproperty name name value Spring//bean/beans我们可以去进行测试了 Test public void test(){//解析beans.xml文件 , 生成管理相应的Bean对象ApplicationContext context new ClassPathXmlApplicationContext(beans.xml);//getBean : 参数即为spring配置文件中bean的id .Hello hello (Hello) context.getBean(hello);hello.show(); }3.3、思考 Hello 对象是谁创建的 ? 【 hello 对象是由Spring创建的 】Hello 对象的属性是怎么设置的 ? 【hello 对象的属性是由Spring容器设置的 】 这个过程就叫控制反转 : 控制 : 谁来控制对象的创建 , 传统应用程序的对象是由程序本身控制创建的 , 使用Spring后 , 对象是由Spring来创建的反转 : 程序本身不创建对象 , 而变成被动的接收对象 . 依赖注入 : 就是利用set方法来进行注入的. IOC是一种编程思想由主动的编程变成被动的接收 可以通过newClassPathXmlApplicationContext去浏览一下底层源码 . 3.4、修改案例一 我们在案例一中 新增一个Spring配置文件beans.xml ?xml version1.0 encodingUTF-8? beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://www.springframework.org/schema/beanshttps://www.springframework.org/schema/beans/spring-beans.xsdbean idmysqllimpl classcom.shelly.dao.UserDaoMySQLlmpl/bean idoraclelimpl classcom.shelly.dao.UserDaoMySQLlmpl/bean idUserServiceImpl classcom.shelly.service.UserServiceImp1!--ref:引用Spring容器中创建好的对象value具体的值基本数据类型--property nameuserDao refmysqllimpl//bean/beans测试 import com.shelly.dao.UserDaoImp1; import com.shelly.dao.UserDaoMySQLlmpl; import com.shelly.dao.UserDaoOracleimpl; import com.shelly.service.UserService; import com.shelly.service.UserServiceImp1; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;/*** ClassName: MyTest* Package: PACKAGE_NAME* Description** Author Shelly* Create 2023/5/10 22:45* Version 1.0*/ public class MyTest {public static void main(String[] args) { // //用户实际调用的是业务层dao层他们不需要接触 // UserService userService new UserServiceImp1(); // // //((UserServiceImp1) userService).setUserDao(new UserDaoMySQLlmpl()); // ((UserServiceImp1) userService).setUserDao(new UserDaoOracleimpl()); // userService.getUser(); ////获取ApplicationContext:拿到Spring的容器ApplicationContext context new ClassPathXmlApplicationContext(beans.xml);//容器在手天下我有需要什么就直接get什么UserServiceImp1 userServiceImpl (UserServiceImp1) context.getBean(UserServiceImpl);userServiceImpl.getUser();} }OK , 到了现在 , 我们彻底不用再程序中去改动了 , 要实现不同的操作 , 只需要在xml配置文件中进行修改 , 所谓的IoC,一句话搞定 : 对象由Spring 来创建 , 管理 , 装配 ! 4、IOC创建对象的方式 4.1、使用无参构造创建对象默认 User.java public class User {private String name;public User() {System.out.println(user无参构造方法);}public void setName(String name) {this.name name;}public void show(){System.out.println(name name );} }beans.xml ?xml version1.0 encodingUTF-8? beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://www.springframework.org/schema/beanshttps://www.springframework.org/schema/beans/spring-beans.xsdbean iduser classcom.shelly.pojo.Userproperty namename value杨洋//bean/beans测试类 import com.shelly.pojo.User; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;/*** ClassName: MyTest* Package: PACKAGE_NAME* Description** Author Shelly* Create 2023/5/11 10:52* Version 1.0*/ public class MyTest {public static void main(String[] args) {ApplicationContext context new ClassPathXmlApplicationContext(beans.xml);//在执行getBean的时候, user已经创建好了 , 通过无参构造User user (User) context.getBean(user);//调用对象的方法 user.show();} }结果可以发现在调用show方法之前User对象已经通过无参构造初始化了 4.2、使用有参构造创建对象 使用无参构造创建对象默认假设我们要使用有参构造创建对象 下标赋值 !-- 第一种根据index参数下标设置 -- bean iduserT classcom.kuang.pojo.UserT!-- index指构造方法 , 下标从0开始 --constructor-arg index0 valuekuangshen2/ /bean类型 2. !-- 第三种根据参数类型设置不建议使用 -- 3. bean iduserT classcom.kuang.pojo.UserT 4. constructor-arg typejava.lang.String valuekuangshen2/ 5. /bean参数名 !-- 第二种根据参数名字设置 -- bean iduserT classcom.kuang.pojo.UserT!-- name指参数名 --constructor-arg namename valuekuangshen2/ /bean总结在配置文件加载的时候容器中管理的对象就已经初始化了。 5、Spring配置 5.1、别名 alias 设置别名 , 为bean设置别名 , 可以设置多个别名 !--设置别名在获取Bean的时候可以使用别名获取-- alias nameuserT aliasuserNew/5.2、Bean的配置 !--bean就是java对象,由Spring创建和管理-- !--id 是bean的标识符,要唯一,如果没有配置id,name就是默认标识符如果配置id,又配置了name,那么name是别名name可以设置多个别名,可以用逗号,分号,空格隔开如果不配置id和name,可以根据applicationContext.getBean(.class)获取对象;class是bean的全限定名包名类名 -- bean idhello namehello2 h2,h3;h4 classcom.kuang.pojo.Helloproperty namename valueSpring/ /bean5.3、import 这个import一般用于团队开发使用他可以将多个配置文件导入合并为一个 假设现在项目中有多个人开发这三个人复制不同的类开发不同的类需要注册在不同的bean中我们可以利用import将所有人的beans.xml合并为一个总的 张三 李四 王五 applicationContext.xml import resource{path}/beans.xml/ 使用的时候直接使用总的配置就可以了。 6、依赖注入 6.1、构造器注入 前面4.1、4.2通过无参和有参的构造器注入 6.2、Set方式注入【重点】 依赖注入Set注入 依赖bean对象的创建依赖于容器注入bean对象中的所有属性由容器来注入 【环境搭建】 复杂类型 public Address{private String address;public string getAddress() {return address;}public void setAddress(Address address) {this.address address;} }真实测试对象 public class Student {private String name;private Address address;private String[] books;private ListString hobbys;private MapString,String card;private SetString games;private String wife;private Properties info; }beans.xml ?xml version1.0 encodingUTF-8? beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://www.springframework.org/schema/beanshttps://www.springframework.org/schema/beans/spring-beans.xsdbean idstudent classcom.shelly.pojo.Student!--第一种普通值注入value--property namename valueyangyang//bean/beansTest测试 public class MyTest {public static void main(String[] args) {ApplicationContext context new ClassPathXmlApplicationContext(beans.xml);Student student (Student) context.getBean(student);student.getAddress();} }完善注入信息 常量注入 bean idstudent classcom.kuang.pojo.Studentproperty namename value小明/ /beanBean注入 注意点这里的值是一个引用ref bean idaddr classcom.kuang.pojo.Addressproperty nameaddress value重庆/ /bean bean idstudent classcom.kuang.pojo.Studentproperty namename value小明/property nameaddress refaddr/ /bean数组注入 bean idstudent classcom.kuang.pojo.Studentproperty namename value小明/property nameaddress refaddr/property namebooksarrayvalue西游记/valuevalue红楼梦/valuevalue水浒传/value/array/property /beanList注入 property namehobbyslistvalue听歌/valuevalue看电影/valuevalue爬山/value/list /propertyMap注入 property namecardmapentry key中国邮政 value456456456465456/entry key建设 value1456682255511//map /propertyset注入 property namegamessetvalueLOL/valuevalueBOB/valuevalueCOC/value/set /propertyNull注入 property namewifenull//propertyProperties注入 property nameinfopropsprop key学号20190604/propprop key性别男/propprop key姓名小明/prop/props /property测试结果 6.3、拓展方式注入 我们可以使用p命令空间和c命令空间进行注入 官方解释 User.java 【注意这里没有有参构造器】 public class User {private String name;private int age;public void setName(String name) {this.name name;}public void setAge(int age) {this.age age;}Overridepublic String toString() {return User{ name name \ , age age };} }p命名空间注入 : 需要在头文件中假如约束文件 导入约束 : xmlns:phttp://www.springframework.org/schema/p !--P(属性: properties)命名空间 , 属性依然要设置set方法-- bean iduser classcom.kuang.pojo.User p:name狂神 p:age18/c 命名空间注入 : 需要在头文件中假如约束文件 导入约束 : xmlns:chttp://www.springframework.org/schema/c !--C(构造: Constructor)命名空间 , 属性依然要设置set方法-- bean iduser classcom.kuang.pojo.User c:name狂神 c:age18/发现问题爆红了刚才我们没有写有参构造 解决把有参构造器加上这里也能知道c 就是所谓的构造器注入 测试 Test public void test02(){ApplicationContext context new ClassPathXmlApplicationContext(applicationContext.xml);User user (User) context.getBean(user);System.out.println(user); }注意点p命名和c命名空间不能直接使用需要导入xml约束。 6.4、Bean的作用域 官方解释 单例模式Spring默认机制 bean idServiceImpl classcn.csdn.service.ServiceImpl c:age18 c:name狂神“ scopesingleton原型模式每次从容器中get的时候都会产生一个新对象 bean idaccount classcom.foo.DefaultAccount scopeprototype/ 或者 bean idaccount classcom.foo.DefaultAccount singletonfalse/其余的request、session、application这些只能在web开发中使用到。 7、Bean的自动装配 自动装配是使用spring满足bean依赖的一种方法spring会在应用上下文中为某个bean寻找其依赖的bean。 Spring中bean有三种装配机制分别是 在xml中显式配置在java中显式配置隐式的bean发现机制和自动装配。【重点】 推荐不使用自动装配xml配置 , 而使用注解 . 7.1、测试 环境搭建一个人有两个宠物 7.2、ByName自动装配 ?xml version1.0 encodingUTF-8? beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://www.springframework.org/schema/beanshttps://www.springframework.org/schema/beans/spring-beans.xsdbean idcat classcom.shelly.pojo.Cat/bean iddog classcom.shelly.pojo.Dog/!--byName会自动在容器上下文中查找和自己对象set方法后面的值对应的beanidbyType会自动在容器上下文查找和自己对象属性类型相同的bean--bean idpeople classcom.shelly.pojo.People autowirebyNameproperty namename valueyangyang//bean/beans7.3、ByType自动装配 ?xml version1.0 encodingUTF-8? beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://www.springframework.org/schema/beanshttps://www.springframework.org/schema/beans/spring-beans.xsdbean idcat classcom.shelly.pojo.Cat/bean iddog classcom.shelly.pojo.Dog/!--byName会自动在容器上下文中查找和自己对象set方法后面的值对应的beanidbyType会自动在容器上下文查找和自己对象属性类型相同的bean--bean idpeople classcom.shelly.pojo.People autowirebyTypeproperty namename valueyangyang//bean/beans小结 byName的时候需要保证所有bean的id唯一并且这个bean需要和自动注入的属性的set方法的值一致。byTest的时候需要保证所有bean的clas唯一并且这个bean需要和自动注入的属性的类型一致。 7.4、使用注解实现自动装配 jdk1.5开始支持注解spring2.5开始全面支持注解。 要使用注解须知 导入约束 配置注解的支持【重要】 context:annotation-config/xmlns:contexthttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsdAutowrited 直接在属性上使用即可。 也可以在set方式上使用。 使用Autowrited我们可以不用编写Set方法里前提是自动装配的属性在IOCSpring容器中存在且符合名字byName 科普 Nullable 字段标记了这个注解说明这个字段可以为nullAutowired(requiredfalse) 说明 false对象可以为nulltrue对象必须存对象不能为null。 //如果允许对象为null设置required false,默认为true Autowired(required false) private Cat cat;如果Autowired自动装配的环境比较复杂自动装配无法通过一个注解【Autowired】完成的时候我们可以使用Qualifier(value”xxx”)去配置Autowired的使用指定一个唯一的bean对象注入 Qualifier Autowired是根据类型自动装配的加上Qualifier则可以根据byName的方式自动装配Qualifier不能单独使用。 Resource Resource如有指定的name属性先按该属性进行byName方式查找装配其次再进行默认的byName方式进行装配如果以上都不成功则按byType的方式自动装配。都不成功则报异常。 public class User {//如果允许对象为null设置required false,默认为trueResource(name cat2)private Cat cat;Resourceprivate Dog dog;private String str; }小结 Autowired与Resource异同 Autowired与Resource都可以用来装配bean。都可以写在字段上或写在setter方法上。Autowired默认按类型装配属于spring规范默认情况下必须要求依赖对象必须存在如果要允许null 值可以设置它的required属性为false如Autowired(requiredfalse) 如果我们想使用名称装配可以结合Qualifier注解进行使用Resource属于J2EE复返默认按照名称进行装配名称可以通过name属性进行指定。如果没有指定name属性当注解写在字段上时默认取字段名进行按照名称查找如果注解写在setter方法上默认取属性名进行装配。 当找不到与名称匹配的bean时才按照类型进行装配。但是需要注意的是如果name属性一旦指定就只会按照名称进行装配。 它们的作用相同都是用注解方式注入对象但执行顺序不同。Autowired先byTypeResource先byName。 都是用来自动装配的都可以放在属性字段上Autowired通过byType的方式实现而且必须要求这个对象存在【常用】Resource默认通过byName的方式实现如果找不到名字则通过byType实现。如果两个都找不到的情况下就报错。【常用】执行顺序不同Autowired通过byType的方式实现。Resource默认通过byName的方式实现。 8、使用注解开发 8.1、说明 在spring4之后想要使用注解形式必须得要引入aop的包 在配置文件当中还得要引入一个context约束 ?xml version1.0 encodingUTF-8? beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexmlns:contexthttp://www.springframework.org/schema/contextxsi:schemaLocationhttp://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdcontext:annotation-config//beans8.2、Bean的实现 bean ?xml version1.0 encodingUTF-8? beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexmlns:contexthttp://www.springframework.org/schema/contextxsi:schemaLocationhttp://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd!--指定要扫描的包这个包下的注解就会生效--context:component-scan base-packagecom.shelly.pojo/context:annotation-config/!--bean iduser classcom.shelly.pojo.User/--!-- bean iduser classcom.shelly.pojo.Userproperty namename valueyangyang//bean--/beans属性如何注入 package com.shelly.pojo;import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component;/*** ClassName: User* Package: com.shelly.dao* Description** Author Shelly* Create 2023/5/12 20:51* Version 1.0*///等价于bean iduser classcom.shelly.pojo.User/ Component public class User {public String name;//相当于property namename valueyangyang/Value(yangyang)public void setName(String name) {this.name name;} }衍生的注解 Component 有几个衍生注解我们在web开发中会按照mvc三层架构分层。 dao 【Repository】service【Service】controller 【Controller 】 这四个注解功能都是一样的都是代表将某个类注册到Spring中装配Bean 自动装配置 - Autowired:自动装配通过类型、名字如果Autowired不能唯一自动装配上属性则需要通过Qualifier(value”xxx”) - Nullable 字段标记了这个注解说明这个字段可以为null - Resource:自动装配通过名字、类型作用域 scope singleton默认的Spring会采用单例模式创建这个对象。关闭工厂 所有的对象都会销毁。prototype多例模式。关闭工厂 所有的对象不会销毁。内部的垃圾回收机制会回收 Controller(user) Scope(prototype) public class User {Value(秦疆)public String name; }小结 XML与注解 XML更加万能适用于任何场合维护简单方便注解不是自己类使用不了维护相对复杂 xml与注解整合开发 推荐最佳实践 xml管理Bean 注解完成属性注入 使用过程中 只需要注意一个问题必须让注解生效就需要开启注解的支持 !--指定要扫描的包这个包下的注解就会生效-- context:component-scan base-packagecom.shelly.pojo/ context:annotation-config/9、使用Java的方式配置Spring 我们现在要完全不使用Spring的xml配置了全权交给Java来做。 JavaConfig 原来是 Spring 的一个子项目它通过 Java 类的方式提供 Bean 的定义信息在 Spring4 的版本 JavaConfig 已正式成为 Spring4 的核心功能 。 实体类 package com.shelly.pojo;import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component;/*** ClassName: User* Package: com.shelly.pojo* Description** Author Shelly* Create 2023/5/12 21:36* Version 1.0*///这里的注解说明这个类被Spring接管类注册到了容器中 Component public class User {private String name;public String getName() {return name;}Value(YangYang) //属性注入值public void setName(String name) {this.name name;}Overridepublic String toString() {return User{ name name \ };} }配置文件 package com.shelly.config;import com.shelly.pojo.User; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import;/*** ClassName: MyConfig* Package: com.shelly.config* Description** Author Shelly* Create 2023/5/12 21:38* Version 1.0*///这个也会被Spring容器托管注册到容器中因为它本来就是一个Configuration // Configuration代表这是一个配置类就和我们之前看的beans.xml Configuration ComponentScan(com.shelly.pojo) Import(MyConfig2.class) public class MyConfig {//注册一个bean就相当于我们之前写的一个bean标签//这个方法的名字就相当于bean标签中的id属性//这个方法的返回值就相当于bean标签中的class属性Beanpublic User getuser(){return new User();//就是返回要注入到bean的对象} }测试类 import com.shelly.config.MyConfig; import com.shelly.pojo.User; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext;/*** ClassName: MyTest* Package: PACKAGE_NAME* Description** Author Shelly* Create 2023/5/12 21:44* Version 1.0*/ public class MyTest {public static void main(String[] args) {//如果完全使用了配置类方式去做我们就只能通过AnnotationConfig上下文来获取容器通过配置类的class对象加载ApplicationContext context new AnnotationConfigApplicationContext(MyConfig.class);User getUser (User) context.getBean(user, User.class);System.out.println(getUser.getName());} }这种纯Java的配置方式在Spring Boot中随处可见。 10、代理模式 为什么要学习代理模式因为SpringAOP的底层机制就是动态代理【SpringAOP和SpringMVC】 代理模式 静态代理动态代理 学习aop之前 , 我们要先了解一下代理模式 10.1、静态代理 静态代理角色分析 抽象角色 : 一般使用接口或者抽象类来实现真实角色 : 被代理的角色代理角色 : 代理真实角色 ; 代理真实角色后 , 一般会做一些附属的操作 .客户 : 使用代理角色来进行一些操作 代理步骤 接口 //租房 public interface Rent {public void rent(); }真实角色 //房东 public class Host implements Rent{public void rent(){System.out.println(房东要出租房子);} }代理角色 public class Proxy implements Rent{private Host host;public Proxy(){}public Proxy(Host host) {this.host host;}//租房public void rent(){seeHouse();host.rent();fare();}//看房public void seeHouse(){System.out.println(中介带你看房);}//收中介费public void fare(){System.out.println(收中介费);} }客户访问代理角色 public class Client {public static void main(String[] args) {//房东要租房Host host new Host();//中介帮助房东Proxy proxy new Proxy(host);//你去找中介proxy.rent();} }10.2、静态代理的好处 可以使得我们的真实角色更加纯粹 . 不再去关注一些公共的事情 .公共的业务由代理来完成 . 实现了业务的分工 ,公共业务发生扩展时变得更加集中和方便 . 缺点 : 类多了 , 多了代理类 , 工作量变大了开发效率降低 我们想要静态代理的好处又不想要静态代理的缺点所以 , 就有了动态代理 ! 10.3、加深理解静态代理 练习步骤 创建一个抽象角色比如咋们平时做的用户业务抽象起来就是增删改查 //抽象角色增删改查业务 public interface UserService { void add(); void delete(); void update(); void query();}我们需要一个真实对象来完成这些增删改查操作 //真实对象完成增删改查操作的人 public class UserServiceImpl implements UserService {public void add() {System.out.println(增加了一个用户);}public void delete() {System.out.println(删除了一个用户);}public void update() {System.out.println(更新了一个用户);}public void query() {System.out.println(查询了一个用户);} 需求来了现在我们需要增加一个日志功能怎么实现 思路1 在实现类上增加代码 【麻烦】思路2使用代理来做能够不改变原来的业务情况下实现此功能就是最好的了 设置一个代理类来处理日志 代理角色 //代理角色在这里面增加日志的实现 public class UserServiceProxy implements UserService {private UserServiceImpl userService;public void setUserService(UserServiceImpl userService) {this.userService userService;}public void add() {log(add);userService.add();}public void delete() {log(delete);userService.delete();}public void update() {log(update);userService.update();}public void query() {log(query);userService.query();}public void log(String msg){System.out.println(执行了msg方法);} }测试访问类 public class Client {public static void main(String[] args) {//真实业务UserServiceImpl userService new UserServiceImpl();//代理类UserServiceProxy proxy new UserServiceProxy();//使用代理类实现日志功能proxy.setUserService(userService);proxy.add();} }OK到了现在代理模式大家应该都没有什么问题了重点大家需要理解其中的思想 我们在不改变原来的代码的情况下实现了对原有功能的增强这是AOP中最核心的思想 【聊聊AOP纵向开发横向开发】 10.4、动态代理 动态代理的角色和静态代理的一样动态代理的代理类是动态生成的。静态代理的代理类是我们提前写好的动态代理分为两类 : 一类是基于接口动态代理 , 一类是基于类的动态代理 基于接口的动态代理——JDK动态代理基于类的动态代理—cglibJava字节码实现现在用的比较多的是 javasist 来生成动态代理我们这里使用JDK的原生代码来实现其余的道理都是一样的 动态代理的好处 静态代理有的它都有静态代理没有的它也有 可以使得我们的真实角色更加纯粹 . 不再去关注一些公共的事情 .公共的业务由代理来完成 . 实现了业务的分工 ,公共业务发生扩展时变得更加集中和方便 .一个动态代理 , 一般代理某一类业务一个动态代理可以代理多个类代理的是接口 11、AOP 一句话总结AOP思想是一种横向编程的思想在不影响原来业务类的情况下实现动态的增强。 11.1、什么是AOP AOPAspect Oriented Programming意为面向切面编程通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续是软件开发中的一个热点也是Spring框架中的一个重要内容是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离从而使得业务逻辑各部分之间的耦合度降低提高程序的可重用性同时提高了开发的效率。 11.2、AOP在Spring中的作用 提供声明式事务允许用户自定义切面 横切关注点跨越应用程序多个模块的方法或功能。即是与我们业务逻辑无关的但是我们需要关注的部分就是横切关注点。如日志 , 安全 , 缓存 , 事务等等 ….切面ASPECT横切关注点 被模块化 的特殊对象。即它是一个类。通知Advice切面必须要完成的工作。即它是类中的一个方法。目标Target被通知对象。代理Proxy向目标对象应用通知之后创建的对象。切入点PointCut切面通知 执行的 “地点”的定义。连接点JointPoint与切入点匹配的执行点。 SpringAOP中通过Advice定义横切逻辑Spring中支持5种类型的Advice: 即 Aop 在 不改变原有代码的情况下 , 去增加新的功能。 11.3、使用Spring 实现AOP 【重点】使用AOP织入需要导入一个依赖包 !-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -- dependencygroupIdorg.aspectj/groupIdartifactIdaspectjweaver/artifactIdversion1.9.4/version /dependency方式一使用Spring 的API接口【使用SpringAPI接口实现】 首先编写我们的业务接口和实现类 public interface UserService {public void add();public void delete();public void update();public void search(); }public class UserServiceImpl implements UserService{Overridepublic void add() {System.out.println(增加用户);}Overridepublic void delete() {System.out.println(删除用户);}Overridepublic void update() {System.out.println(更新用户);}Overridepublic void search() {System.out.println(查询用户);} }然后去写我们的增强类 , 我们编写两个 , 一个前置增强 一个后置增强 public class Log implements MethodBeforeAdvice {//method : 要执行的目标对象的方法//objects : 被调用的方法的参数//Object : 目标对象Overridepublic void before(Method method, Object[] objects, Object o) throws Throwable {System.out.println( o.getClass().getName() 的 method.getName() 方法被执行了);} }public class AfterLog implements AfterReturningAdvice {//returnValue 返回值//method被调用的方法//args 被调用的方法的对象的参数//target 被调用的目标对象Overridepublic void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {System.out.println(执行了 target.getClass().getName()的method.getName()方法,返回值returnValue);} }最后去spring的文件中注册 , 并实现aop切入实现 , 注意导入约束 ?xml version1.0 encodingUTF-8? beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexmlns:aophttp://www.springframework.org/schema/aopxsi:schemaLocationhttp://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd!--注册bean--bean iduserService classcom.kuang.service.UserServiceImpl/bean idlog classcom.kuang.log.Log/bean idafterLog classcom.kuang.log.AfterLog/!--aop的配置--aop:config!--切入点 expression:表达式匹配要执行的方法--aop:pointcut idpointcut expressionexecution(* com.kuang.service.UserServiceImpl.*(..))/!--执行环绕; advice-ref执行方法 . pointcut-ref切入点--aop:advisor advice-reflog pointcut-refpointcut/aop:advisor advice-refafterLog pointcut-refpointcut//aop:config /beans测试 public class MyTest {Testpublic void test(){ApplicationContext context new ClassPathXmlApplicationContext(beans.xml);UserService userService (UserService) context.getBean(userService);userService.search();} }op的重要性 : 很重要 . 一定要理解其中的思路 , 主要是思想的理解这一块 . Spring的Aop就是将公共的业务 (日志 , 安全等) 和领域业务结合起来 , 当执行领域业务时 , 将会把公共业务加进来 . 实现公共业务的重复利用 . 领域业务更纯粹 , 程序猿专注领域业务 , 其本质还是动态代理 . 方式二自定义来实现AOP【主要是切面定义】 目标业务类不变依旧是userServiceImpl 写我们自己的一个切入类 public class DiyPointcut {public void before(){System.out.println(---------方法执行前---------);}public void after(){System.out.println(---------方法执行后---------);} }去Spring中配置 !--第二种方式自定义实现-- !--注册bean-- bean iddiy classcom.kuang.config.DiyPointcut/ !--aop的配置-- aop:config!--第二种方式使用AOP的标签实现--!--自定义切面ref要引用的类--aop:aspect refdiy!--切入点--aop:pointcut iddiyPonitcut expressionexecution(* com.kuang.service.UserServiceImpl.*(..))/!--通知--aop:before pointcut-refdiyPonitcut methodbefore/aop:after pointcut-refdiyPonitcut methodafter//aop:aspect /aop:config测试 public class MyTest {Testpublic void test(){ApplicationContext context new ClassPathXmlApplicationContext(beans.xml);UserService userService (UserService) context.getBean(userService);userService.add();} }方式三使用注解实现 第一步编写一个注解实现的增强类 package com.kuang.config; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; Aspect public class AnnotationPointcut {Before(execution(* com.kuang.service.UserServiceImpl.*(..)))public void before(){System.out.println(---------方法执行前---------);}After(execution(* com.kuang.service.UserServiceImpl.*(..)))public void after(){System.out.println(---------方法执行后---------);}Around(execution(* com.kuang.service.UserServiceImpl.*(..)))public void around(ProceedingJoinPoint jp) throws Throwable {System.out.println(环绕前);System.out.println(签名:jp.getSignature());//执行目标方法proceedObject proceed jp.proceed();System.out.println(环绕后);System.out.println(proceed);} }第二步在Spring配置文件中注册bean并增加支持注解的配置 !--第三种方式:注解实现-- bean idannotationPointcut classcom.kuang.config.AnnotationPointcut/ aop:aspectj-autoproxy/aop:aspectj-autoproxy说明 通过aop命名空间的aop:aspectj-autoproxy /声明自动为spring容器中那些配置aspectJ切面的bean创建代理织入切面。 当然spring 在内部依旧采用AnnotationAwareAspectJAutoProxyCreator进行自动代理的创建工作但具体实现的细节已经 被aop:aspectj-autoproxy /隐藏起来了 aop:aspectj-autoproxy /有一个proxy-target-class属性默认为false表示使用jdk动态代理织入增强当配为 aop:aspectj-autoproxy poxy-target-classtrue/时表示使用CGLib动态代理技术织入增强。不过即使proxy-target-class设置 为false如果目标类没有声明接口则spring将自动使用CGLib动态代理。12、整合Mybatis 步骤 导入相关jar包 Junitmybatismysql数据库spring相关的aop织入mybatis-spring 编写配置文件测试 步骤 导入相关jar包 Junit dependencygroupIdjunit/groupIdartifactIdjunit/artifactIdversion4.12/version /dependencymybatis dependencygroupIdorg.mybatis/groupIdartifactIdmybatis/artifactIdversion3.5.2/version /dependencymysql数据库 mysql-connector-java dependencygroupIdmysql/groupIdartifactIdmysql-connector-java/artifactIdversion5.1.47/version /dependencyspring相关 dependencygroupIdorg.springframework/groupIdartifactIdspring-webmvc/artifactIdversion5.1.10.RELEASE/version /dependency dependencygroupIdorg.springframework/groupIdartifactIdspring-jdbc/artifactIdversion5.1.10.RELEASE/version /dependencyaspectJ AOP 织入器 !-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -- dependencygroupIdorg.aspectj/groupIdartifactIdaspectjweaver/artifactIdversion1.9.4/version /dependencymybatis-spring整合包 【重点】 dependencygroupIdorg.mybatis/groupIdartifactIdmybatis-spring/artifactIdversion2.0.2/version /dependency配置Maven静态资源过滤问题 buildresourcesresourcedirectorysrc/main/java/directoryincludesinclude**/*.properties/includeinclude**/*.xml/include/includesfilteringtrue/filtering/resource/resources /build编写配置文件 测试 12.1、回忆Mybatis 编写pojo实体类 package com.kuang.pojo; public class User {private int id; //idprivate String name; //姓名private String pwd; //密码 }实现mybatis的配置文件 ?xml version1.0 encodingUTF-8 ? !DOCTYPE configurationPUBLIC -//mybatis.org//DTD Config 3.0//ENhttp://mybatis.org/dtd/mybatis-3-config.dtd configurationtypeAliasespackage namecom.kuang.pojo//typeAliasesenvironments defaultdevelopmentenvironment iddevelopmenttransactionManager typeJDBC/dataSource typePOOLEDproperty namedriver valuecom.mysql.jdbc.Driver/property nameurl valuejdbc:mysql://localhost:3306/mybatis?useSSLtrueamp;useUnicodetrueamp;characterEncodingutf8/property nameusername valueroot/property namepassword value123456//dataSource/environment/environmentsmapperspackage namecom.kuang.dao//mappers /configurationUserDao接口编写 public interface UserMapper {public ListUser selectUser(); }接口对应的Mapper映射文件 ?xml version1.0 encodingUTF-8 ? !DOCTYPE mapperPUBLIC -//mybatis.org//DTD Mapper 3.0//ENhttp://mybatis.org/dtd/mybatis-3-mapper.dtd mapper namespacecom.kuang.dao.UserMapperselect idselectUser resultTypeUserselect * from user/select /mapper测试类 Test public void selectUser() throws IOException {String resource mybatis-config.xml;InputStream inputStream Resources.getResourceAsStream(resource);SqlSessionFactory sqlSessionFactory new SqlSessionFactoryBuilder().build(inputStream);SqlSession sqlSession sqlSessionFactory.openSession();UserMapper mapper sqlSession.getMapper(UserMapper.class);ListUser userList mapper.selectUser();for (User user: userList){System.out.println(user);}sqlSession.close(); }12.2、MyBatis-Spring学习 引入Spring之前需要了解mybatis-spring包中的一些重要类 http://www.mybatis.org/spring/zh/index.html 什么是 MyBatis-Spring MyBatis-Spring 会帮助你将 MyBatis 代码无缝地整合到 Spring 中。 知识基础 在开始使用 MyBatis-Spring 之前你需要先熟悉 Spring 和 MyBatis 这两个框架和有关它们的术语。这很重要 MyBatis-Spring 需要以下版本 MyBatis-SpringMyBatisSpring 框架Spring BatchJava2.03.55.04.0Java 81.33.43.2.22.1Java 6 如果使用 Maven 作为构建工具仅需要在 pom.xml 中加入以下代码即可 dependencygroupIdorg.mybatis/groupIdartifactIdmybatis-spring/artifactIdversion2.0.2/version /dependency要和 Spring 一起使用 MyBatis需要在 Spring 应用上下文中定义至少两样东西一个 SqlSessionFactory 和至少一个数据映射器类。 在 MyBatis-Spring 中可使用 SqlSessionFactoryBean来创建 SqlSessionFactory。 要配置这个工厂 bean只需要把下面代码放在 Spring 的 XML 配置文件中 bean idsqlSessionFactory classorg.mybatis.spring.SqlSessionFactoryBeanproperty namedataSource refdataSource / /bean注意SqlSessionFactory 需要一个 DataSource数据源。 这可以是任意的 DataSource只需要和配置其它 Spring 数据库连接一样配置它就可以了。 在基础的 MyBatis 用法中是通过 SqlSessionFactoryBuilder 来创建 SqlSessionFactory 的。 而在 MyBatis-Spring 中则使用 SqlSessionFactoryBean 来创建。 在 MyBatis 中你可以使用 SqlSessionFactory 来创建 SqlSession。一旦你获得一个 session 之后你可以使用它来执行映射了的语句提交或回滚连接最后当不再需要它的时候你可以关闭 session。 SqlSessionFactory 有一个唯一的必要属性用于 JDBC 的 DataSource。这可以是任意的 DataSource 对象它的配置方法和其它 Spring 数据库连接是一样的。 一个常用的属性是 configLocation它用来指定 MyBatis 的 XML 配置文件路径。它在需要修改 MyBatis 的基础配置非常有用。通常基础配置指的是 settings 或 typeAliases 元素。 需要注意的是这个配置文件并不需要是一个完整的 MyBatis 配置。确切地说任何环境配置environments数据源DataSource和 MyBatis 的事务管理器transactionManager都会被忽略。SqlSessionFactoryBean 会创建它自有的 MyBatis 环境配置Environment并按要求设置自定义环境的值。 SqlSessionTemplate 是 MyBatis-Spring 的核心。作为 SqlSession 的一个实现这意味着可以使用它无缝代替你代码中已经在使用的 SqlSession。 模板可以参与到 Spring 的事务管理中并且由于其是线程安全的可以供多个映射器类使用你应该总是用 SqlSessionTemplate 来替换 MyBatis 默认的 DefaultSqlSession 实现。在同一应用程序中的不同类之间混杂使用可能会引起数据一致性的问题。 可以使用 SqlSessionFactory 作为构造方法的参数来创建 SqlSessionTemplate 对象。 bean idsqlSession classorg.mybatis.spring.SqlSessionTemplateconstructor-arg index0 refsqlSessionFactory / /bean现在这个 bean 就可以直接注入到你的 DAO bean 中了。你需要在你的 bean 中添加一个 SqlSession 属性就像下面这样 public class UserDaoImpl implements UserDao {private SqlSession sqlSession;public void setSqlSession(SqlSession sqlSession) {this.sqlSession sqlSession;}public User getUser(String userId) {return sqlSession.getMapper...;} }按下面这样注入 SqlSessionTemplate bean iduserDao classorg.mybatis.spring.sample.dao.UserDaoImplproperty namesqlSession refsqlSession / /bean12.3、整合实现一 引入Spring配置文件beans.xml ?xml version1.0 encodingUTF-8? beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd配置数据源替换mybaits的数据源 !--配置数据源数据源有非常多可以使用第三方的也可使使用Spring的-- bean iddataSource classorg.springframework.jdbc.datasource.DriverManagerDataSourceproperty namedriverClassName valuecom.mysql.jdbc.Driver/property nameurl valuejdbc:mysql://localhost:3306/mybatis?useSSLtrueamp;useUnicodetrueamp;characterEncodingutf8/property nameusername valueroot/property namepassword value123456/ /bean配置SqlSessionFactory关联MyBatis !--配置SqlSessionFactory-- bean idsqlSessionFactory classorg.mybatis.spring.SqlSessionFactoryBeanproperty namedataSource refdataSource/!--关联Mybatis--property nameconfigLocation valueclasspath:mybatis-config.xml/property namemapperLocations valueclasspath:com/kuang/dao/*.xml/ /bean注册sqlSessionTemplate关联sqlSessionFactory !--注册sqlSessionTemplate , 关联sqlSessionFactory-- bean idsqlSession classorg.mybatis.spring.SqlSessionTemplate!--利用构造器注入--constructor-arg index0 refsqlSessionFactory/ /bean增加Dao接口的实现类私有化sqlSessionTemplate public class UserDaoImpl implements UserMapper {//sqlSession不用我们自己创建了Spring来管理private SqlSessionTemplate sqlSession;public void setSqlSession(SqlSessionTemplate sqlSession) {this.sqlSession sqlSession;}public ListUser selectUser() {UserMapper mapper sqlSession.getMapper(UserMapper.class);return mapper.selectUser();} }注册bean实现 bean iduserDao classcom.kuang.dao.UserDaoImplproperty namesqlSession refsqlSession/ /bean测试 Testpublic void test2(){ApplicationContext context new ClassPathXmlApplicationContext(beans.xml);UserMapper mapper (UserMapper) context.getBean(userDao);ListUser user mapper.selectUser();System.out.println(user);}结果成功输出现在我们的Mybatis配置文件的状态发现都可以被Spring整合 ?xml version1.0 encodingUTF-8 ? !DOCTYPE configurationPUBLIC -//mybatis.org//DTD Config 3.0//ENhttp://mybatis.org/dtd/mybatis-3-config.dtd configurationtypeAliasespackage namecom.kuang.pojo//typeAliases /configuration12.4、整合实现二 mybatis-spring1.2.3版以上的才有这个 . 官方文档截图 : dao继承Support类 , 直接利用 getSqlSession() 获得 , 然后直接注入SqlSessionFactory . 比起方式1 , 不需要管理SqlSessionTemplate , 而且对事务的支持更加友好 . 可跟踪源码查看 测试 将我们上面写的UserDaoImpl修改一下 public class UserDaoImpl extends SqlSessionDaoSupport implements UserMapper {public ListUser selectUser() {UserMapper mapper getSqlSession().getMapper(UserMapper.class);return mapper.selectUser();} }修改bean的配置 bean iduserDao classcom.kuang.dao.UserDaoImplproperty namesqlSessionFactory refsqlSessionFactory / /bean测试 Test public void test2(){ApplicationContext context new ClassPathXmlApplicationContext(beans.xml);UserMapper mapper (UserMapper) context.getBean(userDao);ListUser user mapper.selectUser();System.out.println(user); }总结 : 整合到spring中以后可以完全不要mybatis的配置文件除了这些方式可以实现整合之外我们还可以使用注解来实现这个等我们后面学习SpringBoot的时候还会测试整合 13、声明式事务 13.1、回顾事务 把一组业务当成一个业务来做要么都成功要么都失败事务在项目开发中十分的重要涉及到数据的一致性问题不能马虎确保完整性和一致性 事务ACID原则 原子性atomicity事务是原子性操作由一系列动作组成事务的原子性确保动作要么全部完成要么完全不起作用一致性consistency一旦所有事务动作完成事务就要被提交。数据和资源处于一种满足业务规则的一致性状态中隔离性isolation可能多个事务会同时处理相同的数据因此每个事务都应该与其他事务隔离开来防止数据损坏持久性durability事务一旦完成无论系统发生什么错误结果都不会受到影响。通常情况下事务的结果被写到持久化存储器中 13.2、测试 将上面的代码拷贝到一个新项目中 在之前的案例中我们给userDao接口新增两个方法删除和增加用户 //添加一个用户 int addUser(User user); //根据id删除用户 int deleteUser(int id);mapper文件我们故意把 deletes 写错测试 insert idaddUser parameterTypecom.kuang.pojo.Userinsert into user (id,name,pwd) values (#{id},#{name},#{pwd})/insertdelete iddeleteUser parameterTypeintdeletes from user where id #{id} /delete编写接口的实现类在实现类中我们去操作一波 public class UserDaoImpl extends SqlSessionDaoSupport implements UserMapper {//增加一些操作public ListUser selectUser() {User user new User(4,小明,123456);UserMapper mapper getSqlSession().getMapper(UserMapper.class);mapper.addUser(user);mapper.deleteUser(4);return mapper.selectUser();}//新增public int addUser(User user) {UserMapper mapper getSqlSession().getMapper(UserMapper.class);return mapper.addUser(user);}//删除public int deleteUser(int id) {UserMapper mapper getSqlSession().getMapper(UserMapper.class);return mapper.deleteUser(id);} }测试 Test public void test2(){ApplicationContext context new ClassPathXmlApplicationContext(beans.xml);UserMapper mapper (UserMapper) context.getBean(userDao);ListUser user mapper.selectUser();System.out.println(user); }报错sql异常delete写错了 结果 插入成功 没有进行事务的管理我们想让他们都成功才成功有一个失败就都失败我们就应该需要事务 以前我们都需要自己手动管理事务十分麻烦 但是Spring给我们提供了事务管理我们只需要配置即可 13.3、Spring中的事务管理 Spring在不同的事务管理API之上定义了一个抽象层使得开发人员不必了解底层的事务管理API就可以使用Spring的事务管理机制。Spring支持编程式事务管理和声明式的事务管理。 编程式事务管理需要在代码中进行事务的管理 将事务管理代码嵌到业务方法中来控制事务的提交和回滚缺点必须在每个事务操作业务逻辑中包含额外的事务管理代码 声明式事务管理AOP 一般情况下比编程式事务好用。将事务管理代码从业务方法中分离出来以声明的方式来实现事务管理。将事务管理作为横切关注点通过aop方法模块化。Spring中通过Spring AOP框架支持声明式事务管理。 使用Spring管理事务注意头文件的约束导入 : tx xmlns:txhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd事务管理器 无论使用Spring的哪种事务管理策略编程式或者声明式事务管理器都是必须的。就是 Spring的核心事务管理抽象管理封装了一组独立于技术的方法。 JDBC事务 !--配置声明式事务-- bean idtransactionManager classorg.springframework.jdbc.datasource.DataSourceTransactionManagerproperty namedataSource refdataSource / /bean配置好事务管理器后我们需要去配置事务的通知 !--配置事务通知-- tx:advice idtxAdvice transaction-managertransactionManagertx:attributes!--配置哪些方法使用什么样的事务,配置事务的传播特性--!--新特性add--tx:method nameadd propagationREQUIRED/tx:method namedelete propagationREQUIRED/tx:method nameupdate propagationREQUIRED/tx:method namesearch* propagationREQUIRED/tx:method nameget read-onlytrue/!--全部--tx:method name* propagationREQUIRED/ /tx:attributes /tx:advicespring事务传播特性 事务传播行为就是多个事务方法相互调用时事务如何在这些方法间传播。spring支持7种事务传播行为 propagation_requierd如果当前没有事务就新建一个事务如果已存在一个事务中加入到这个事务中这是最常见的选择。propagation_supports支持当前事务如果没有当前事务就以非事务方法执行。propagation_mandatory使用当前事务如果没有当前事务就抛出异常。propagation_required_new新建事务如果当前存在事务把当前事务挂起。propagation_not_supported以非事务方式执行操作如果当前存在事务就把当前事务挂起。propagation_never以非事务方式执行操作如果当前事务存在则抛出异常。propagation_nested如果当前存在事务则在嵌套事务内执行。如果当前没有事务则执行与propagation_required类似的操作 Spring 默认的事务传播行为是 PROPAGATION_REQUIRED它适合于绝大多数的情况。 假设 ServiveX#methodX() 都工作在事务环境下即都被 Spring 事务增强了假设程序中存在如下的调用链Service1#method1()-Service2#method2()-Service3#method3()那么这 3 个服务类的 3 个方法通过 Spring 的事务传播机制都工作在同一个事务中。 就好比我们刚才的几个方法存在调用所以会被放在一组事务当中 配置AOP 导入aop的头文件 配置事务切入 !--配置aop织入事务-- aop:configaop:pointcut idtxPointcut expressionexecution(* com.kuang.dao.*.*(..))/aop:advisor advice-reftxAdvice pointcut-reftxPointcut/ /aop:config进行测试 删掉刚才插入的数据再次测试 Test public void test2(){ApplicationContext context new ClassPathXmlApplicationContext(beans.xml);UserMapper mapper (UserMapper) context.getBean(userDao);ListUser user mapper.selectUser();System.out.println(user); }思考 为什么需要配置事务 如果不配置事务可能存在数据提交不一致的情况如果我们不在Spring中去配置声明式事务我们就需要在代码中手动配置事务事务在项目开发过程非常重要涉及到数据的一致性的问题不容马虎 总结 Spring是一个思想的学习IOC和AOPSpring的优点IOC其实就是提供一个Set接口控制反转依赖注入Set注入Bean的自动装配名字相同、类型唯一就可以在平时开发中使用不用每次都配使用注解开发重点关注 Autowired 和 Component代理模式动态代理、反射整合MyBatis事务记得导包 参考学习链接狂神SSM教程
http://www.w-s-a.com/news/656332/

相关文章:

  • 群晖wordpress搭建网站网站建设及管理
  • 中山企业网站建设公司抖音代运营合作模式
  • 南通营销网站开发做网站页面多少钱
  • 桂林生活网官方网站云主机和云电脑的区别
  • 内部网络网站怎么做vue做单页面网站
  • 如何建立网站教程wordpress粘帖图片
  • 广东网站备案要多久网站开发 pdf 文字版
  • 学校网站方案帮别人做钓鱼网站吗
  • 如何加强网站建设和信息宣传wordpress 搜索提示
  • 灰色网站怎么做php yaf 网站开发框架
  • 浙江建设网站首页提供做网站公司有哪些
  • 建公司网站报价公司seo是什么级别
  • 可信赖的武进网站建设中山网站建设方案
  • 网站设计方面有什么公司运动鞋网站建设目的
  • 学校门户网站流程建设方案找人做网站 多少钱
  • 网站域名更换相应内容网站策划 要求
  • 百盛联合建设集团网站开发网站的步骤
  • php做网站评价网络公司经营范围可以加技
  • 网站积分的作用保定专业网站建设
  • 莆田做网站公司电话如何提升网站访问速度
  • 网站开发流程步骤 口袋网页访问wordpress
  • 湘潭做网站的公司自助建站教程
  • 做网站推广和头条推广wordpress 验证密码错误
  • 淘宝联盟网站怎么做深圳市创想三维科技有限公司
  • 校园网站建设招标公告php网站开发什么
  • 06628 网页制作与网站开发陕西省交通建设网站
  • 做wish如何利用数据网站暗红色网站
  • 企业 网站备案 法人长春建站模板搭建
  • 网站做快照网站改版 升级的目的
  • 自己做一个网站要多少钱海外推广什么意思