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

湘潭企业网站建设百度一下你就知道了百度一下

湘潭企业网站建设,百度一下你就知道了百度一下,咖啡网站设计,青岛房产网站建设1.Spring框架的介绍 1.1 传统的项目的架构 在传统的项目中#xff0c;一般遵循MVC开发模型。 (1) view层与用户进行交互#xff0c;显示数据或者将数据传输给view层。 (2) 在controller层创建service层对象#xff0c;调用service层中业务方法。 (3) 在service层创建dao…1.Spring框架的介绍 1.1 传统的项目的架构 在传统的项目中一般遵循MVC开发模型。 (1) view层与用户进行交互显示数据或者将数据传输给view层。 (2) 在controller层创建service层对象调用service层中业务方法。 (3) 在service层创建dao层对象调用dao层中操作数据的方法。 (4) dao层进行具体的数据库操作 1.2 传统的项目架构缺陷 程序在一定程度上存在耦合性不利于程序的扩展。在controller中直接创建了service层类的对象。如果service的业务发生了变更那么就需要修改controller层的代码。 在进行程序的扩展时不建议在当前程序的基础上直接修改程序为了保证之前程序的正常一般遵循开闭原则进行维护性的修改对扩展开放对修改关闭。 例如用户注册功能。用户注册从账号、密码、手机号等信息即可。随着行业发展目前要求进行实名认证。 1已注册未认证用户登录时进行认证。 2新用户注册后要求进行认证。 为避免对已有业务的改动可以新建一个service类重写注册方法。则在controller层需要创建新的service对象。每个相关的controller层的代码都需要改动并且每个controller都需要创建对象存在对象的浪费。 面向过程—面向对象----面向接口----面向切面(组件) ArrayList aList new ArrayList(); List aList new LinkedList() 1.3 解决方案 基于每个controller都要修改service的创建问题可以为service定义一个统一的创建方式例如对象工厂模式使用工厂创建对象这样以后使用工厂创建对象的对象需要维护时只需要修改对象工厂即可且可以结合单例模式对象工厂返回单例这样优化了对象重复的浪费问题。 虽然单例工厂能够解决对象的维护和重复问题。但是随着service层的扩大工厂也逐渐臃肿,基本每个service会对应一个factory。基于这种情况则又需要解决工厂臃肿的问题为此可以利用反射技术反射可以创建任意类的对象。但是工厂为保证单例只能存储的对象只有一个而controller层需要使用不同的service层对象为保证对象的有效且反射性能相对较低基于这样的情况则可以定义一个需要创建的对象的清单和一个存储对象的容器根据清单创建对象然后将所有创建service对象进行存储每个controller只需要去容器中获取对象即可这样既解决了单例问题也提高了性能。 1.3.1 代码示例 1.3.2 对象清单 1.3.3 对象容器工厂 package org.springframework.context;public interface ApplicationContext {/*** 获取spring容器创建好的对象* param name* return*/Object getBean(String name);/*** 获取spring容器创建好的对象* param name* return*/T T getBean(String name,ClassT c);}package org.springframework.context.support;import org.dom4j.Document;import org.dom4j.Element;import org.dom4j.io.SAXReader;import org.springframework.context.ApplicationContext;import java.io.InputStream;import java.util.HashMap;import java.util.List;import java.util.Map;/*** spring的核心类*/public class ClassPathXmlApplicationContext implements ApplicationContext {/*** 用于存放id或者name与某个类对象的映射关系*/private MapString,Object objMap new HashMap();public ClassPathXmlApplicationContext(){}public ClassPathXmlApplicationContext(String xmlPath){try {//将spring-context.xml中配置的bean对应的类的对象默认全部创建好SAXReader reader new SAXReader();InputStream ins ClassPathXmlApplicationContext.class.getClassLoader().getResourceAsStream(xmlPath);Document doc reader.read(ins);//读取xml的根标签Element rootElement doc.getRootElement();//拿到beans根标签下的所有bean子标签ListElement childEleList rootElement.elements();for(Element temp : childEleList){//读取某个bean标签的id、name、class的属性值String id temp.attributeValue(id);String name temp.attributeValue(name);String cls temp.attributeValue(class);Object obj Class.forName(cls).newInstance();//以id做key拿到class的全路径创建对象作为value//将键值对存储到objMap中objMap.put(id,obj);//拿到name以,切割 以切割多个字符串做key拿到class的全路径创建对象作为valueString[] nameAtt name.split(,);for(String strName: nameAtt){objMap.put(strName,obj);}}} catch (Exception e) {e.printStackTrace();}}/*** 获取spring容器创建好的对象* param name* return*/Overridepublic Object getBean(String name) {return objMap.get(name);}/*** 获取spring容器创建好的对象* param name* return*/Overridepublic T T getBean(String name, ClassT c) {return (T)objMap.get(name);}} 1.3.4 程序相关类 1.3.4.1 test package com.powernode.test;import com.powernode.domain.Dog;import com.powernode.domain.User;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class SelfSpringTest {public static void main(String[] args) {//启动spring容器ApplicationContext context new ClassPathXmlApplicationContext(spring-context.xml);User u1 context.getBean(u1, User.class);u1.sleep();}} 2.Spring的介绍 2.1 简介 Spring框架是由于软件开发的复杂性而创建的初衷是为了让软件开发更加简单。Spring使用的是简单的JavaBean来完成以前只可能由EJB完成的事情。然而Spring的用途不仅仅限于服务器端的开发。从简单性、可测试性和松耦合性角度而言绝大部分Java应用都可以从Spring中受益。 Web Service,有2个显著特点 1数据格式是xml格式。 2配置繁琐“笨重”对象关联性大需在配置文件中各种配置。 基于这些原因Spring框架提出了IOC/DI控制反转/依赖注入AOP面向切面编程。 Spring框架可在任何类型的部署平台上为基于Java的现代企业应用程序提供全面的编程和配置模型。Spring的关键元素是在应用程序级别的基础架构支持Spring专注于企业应用程序的“管道”以便团队可以专注于应用程序级别的业务逻辑而不必与特定的部署环境建立不必要的联系。 2.2 Spring的核心组件 2.2.1 核心容器 核心容器由 spring-corespring-beansspring-contextspring-context-support和spring-expressionSpELSpring 表达式语言Spring Expression Language等模块组成它们的细节如下 l spring-core 模块提供了框架的基本组成部分包括 IoC 和依赖注入功能。 l spring-beans 模块提供 BeanFactory工厂模式的微妙实现它移除了编码式单例的需要并且可以把配置和依赖从实际编码逻辑中解耦。 l context 模块建立在由 core和 beans 模块的基础上建立起来的它以一种类似于 JNDI 注册的方式访问对象。Context 模块继承自 Bean 模块并且添加了国际化比如使用资源束、事件传播、资源加载和透明地创建上下文比如通过 Servelet 容器等功能。Context 模块也支持 Java EE 的功能比如 EJB、JMX 和远程调用等。ApplicationContext 接口是 Context 模块的焦点。spring-context-support 提供了对第三方库集成到 Spring 上下文的支持比如缓存EhCache, Guava, JCache、邮件JavaMail、调度CommonJ, Quartz、模板引擎FreeMarker, JasperReports, Velocity等。 l spring-expression 模块提供了强大的表达式语言用于在运行时查询和操作对象图。它是 JSP2.1 规范中定义的统一表达式语言的扩展支持 set 和 get 属性值、属性赋值、方法调用、访问数组集合及索引的内容、逻辑算术运算、命名变量、通过名字从 Spring IoC 容器检索对象还支持列表的投影、选择以及聚合等。 依赖关系图如下 2.2.2 数据访问/集成 数据访问/集成层包括 JDBCORMOXMJMS 和事务处理模块它们的细节如下 注JDBCJava Data Base ConnectivityORMObject Relational MappingOXMObject XML MappingJMSJava Message Service l JDBC 模块提供了 JDBC 抽象层它消除了冗长的 JDBC 编码和对数据库供应商特定错误代码的解析。 l ORM 模块提供了对流行的对象关系映射 API 的集成包括 JPA、JDO 和 Hibernate 等。通过此模块可以让这些 ORM 框架和 spring的其它功能整合比如前面提及的事务管理。 l OXM 模块提供了对 OXM 实现的支持比如 JAXB、Castor、XML Beans、JiBX、XStream 等。 l JMS 模块包含生产produce和消费consume消息的功能。从 Spring 4.1 开始集成了 spring-messaging 模块。 l 事务模块为实现特殊接口类及所有的 POJO 支持编程式和声明式事务管理。注编程式事务需要自己写 beginTransaction()、commit()、rollback() 等事务管理方法声明式事务是通过注解或配置由 spring 自动处理编程式事务粒度更细 2.2.3 Web Web 层由 WebWeb-MVCWeb-Socket 和 Web-Portlet 组成它们的细节如下 l Web 模块提供面向 web 的基本功能和面向 web 的应用上下文比如多部分multipart文件上传功能、使用 Servlet 监听器初始化 IoC 容器等。它还包括 HTTP 客户端以及 Spring 远程调用中与 web 相关的部分。 l Web-MVC 模块为 web 应用提供了模型视图控制MVC和 REST Web服务的实现。Spring 的 MVC 框架可以使领域模型代码和 web 表单完全地分离且可以与 Spring 框架的其它所有功能进行集成。 l Web-Socket 模块为 WebSocket-based 提供了支持而且在 web 应用程序中提供了客户端和服务器端之间通信的两种方式。 l Web-Portlet 模块提供了用于 Portlet 环境的 MVC 实现并反映了 spring-webmvc 模块的功能。 2.2.4 其他 还有其他一些重要的模块像 AOPAspectsInstrumentationWeb 和测试模块它们的细节如下 l AOP 模块提供了面向方面切面的编程实现允许你定义方法拦截器和切入点对代码进行干净地解耦从而使实现功能的代码彻底的解耦出来。使用源码级的元数据可以用类似于.Net属性的方式合并行为信息到代码中。 l Aspects 模块提供了与 AspectJ 的集成这是一个功能强大且成熟的面向切面编程AOP框架。 l Instrumentation 模块在一定的应用服务器中提供了类 instrumentation 的支持和类加载器的实现。 l Messaging 模块为 STOMP 提供了支持作为在应用程序中 WebSocket 子协议的使用。它也支持一个注解编程模型它是为了选路和处理来自 WebSocket 客户端的 STOMP 信息。 l 测试模块支持对具有 JUnit 或 TestNG 框架的 Spring 组件的测试。 3.Spring的IOC的使用 IOC、DI IOC控制反转。将对象的创建、初始化、销毁等一系列的生命周期过程交给spring管理。 结婚: 方式1: 自己找女生---------------吃饭、逛街、看电影、送回家等---------结婚 (同学、同事、公交地铁1个月-3个月) 半年-1年半 1天 方式2: 媒婆(1个月)------------------------结婚(1天) 吃饭: 方式1: 买菜、买米(30min-1h)----蒸饭、洗菜、切菜、炒菜(1个小时)—吃(15-30min) 方式2: 定外卖-----------------吃(15-30min) 面向过程-----面向对象-----面向接口-----面向组件(面向切面)–面向服务—面向百度 3.1 基本使用 3.1.1 创建项目并导入spring IoC相关jar包 在pom文件中引入Spring的IoC核心jar包 !--依赖-- dependencies!--引入spring的context依赖可以传递出aop beans core expression--dependencygroupIdorg.springframework/groupIdartifactIdspring-context/artifactIdversion5.3.4/version/dependency /dependencies3.1.2 创建User类 package com.bjpowernode.domain;import java.util.Date;/*** Created on 2021/7/16** author 雷哥*/ public class User {private Integer id;private String name;private Integer age;private String address;private Date birth;public User() {}public Integer getId() {return id;}public void setId(Integer id) {this.id id;}public String getName() {return name;}public void setName(String name) {this.name name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age age;}public String getAddress() {return address;}public void setAddress(String address) {this.address address;}public Date getBirth() {return birth;}public void setBirth(Date birth) {this.birth birth;}Overridepublic String toString() {return User{ id id , name name \ , age age , address address \ , birth birth };} } 3.1.3 创建Spring的核心配置文件spring-context.xml/applicationContext.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/beans http://www.springframework.org/schema/beans/spring-beans.xsd!-- spring 核心配置文件 配置IOC容器中需要创建的bean --bean iduserId nameuser classcom.bjpowernode.domain.User / /beans3.1.4 编写测试程序 public class Test {public static void main(String[] args) {//根据 spring的配置文件 创建 应用容器ApplicationContext context new ClassPathXmlApplicationContext(spring-context.xml);System.out.println(马上获取bean);//从容器中获取 对象User user (User) context.getBean(user);System.out.println(user);} }3.2 Bean标签属性介绍 3.2.1 id 是 bean的唯一标识 一个bean其id 值只能有一个 。整个IOC 容器id 值不允许重复使用名称作为key。 3.2.2 name 一个bean的名称可以存在多个多个之间使用逗号分隔。不论bean有没有定义name属性默认id都会当做name。 3.2.3 class bean的具体的类型包名和类名组成。 3.2.4 scope bean的作用域:如果不写scope则默认为单例 prototype 非单例每次获取都会创建一个新的bean对象。 singleton : 单例多次获取永远同一个bean 默认值。 request 一次请求基于web项目的bean的作用域。 session : 一次会话基于web项目的bean的作用域。 3.2.5 lazy-init 延迟初始化(懒加载)默认只要加载了配置文件。bean对象就会被初始化lazy-init则是获取时才会初始化。只针对单例模式有效非单例每次获取都会创建没有延迟初始化的意义 3.2.6 depends-on 初始化时依赖的对象当前对象初始化前需先初始化depends-on指定的对象 3.2.7 init-method 对象初始化后调用的方法 3.2.8 destroy-method 对象销毁时调用的方法 3.2.9 autowire 属性自动装配 byName 根据属性名称装配 byType 根据类型装配 3.2.10 autowire-candidate 是否允许作为自动装配的候选项 true 作为自动装配的候选项 false 不作为自动装配的候选项 3.2.11 primary 优先使用该bean因为Spring需要支持使用类型查找对象在一个大类型下可能存在多个小类型。如果根据大类型装配属性时不知道使用哪个具体的对象则可以根据primary设置优先级。 3.2.12 代码示例 ?xml version1.0 encodingUTF-8? beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd!-- spring 核心配置文件 配置IOC容器中需要创建的bean --!-- bean iduserId nameuser classcom.bjpowernode.domain.User /--!--id : bean的唯一标识 整个IOC容器不能重复。name : bean的key,多个name之间使用逗号,class : 具体的bean的全路径scope : bean的作用域singleton 单例 默认prototype 非单例lazy-inittrue 获取时创建对象depends-ontest 默认自上而下创建 depends-on 会优先创建 depends-on 对应的beaninit-method : 对象创建后调用的方法destroy-method :对象销毁时调用的方法 容器调用closeautowire : 属性自动装配byName 根据属性名装配byType 根据属性类型装配primary : 当存在多个同样的类型时 primary 为true 则优先使用该bean--bean iduserId2 nameuser1,user2 classcom.bjpowernode.domain.User scopesingleton depends-ontest init-methodinit destroy-methoddestory primarytrue /!-- test类 --bean nametest classcom.bjpowernode.domain.Test /bean nameuserService1 classcom.bjpowernode.service.impl.UserServiceImpl1 primarytrue /bean nameuserService2 classcom.bjpowernode.service.impl.UserServiceImpl2 / /beanspackage com.bjpowernode.service;public interface IUserService { }package com.bjpowernode.service.impl;import com.bjpowernode.service.IUserService;/*** Description: 接口实现类1* author: Mr.T* date 2020-09-26 14:33*/ public class UserServiceImpl1 implements IUserService { }package com.bjpowernode.service.impl;import com.bjpowernode.service.IUserService; public class UserServiceImpl2 implements IUserService { }package com.bjpowernode.domain; public class User {private Integer id;private String name;public User(){System.out.println(构造方法执行 user 对象进行创建);}public void sleep(){System.out.println(早睡早起!!!);}public void init(){System.out.println(对象初始化后调用的方法);}public void destory(){System.out.println(对象销毁时调用);} }package com.bjpowernode.test;import com.bjpowernode.domain.User; import com.bjpowernode.service.IUserService; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;public class Test {public static void main(String[] args) {//根据 spring的配置文件 创建 应用容器ClassPathXmlApplicationContext context new ClassPathXmlApplicationContext(spring-context.xml);System.out.println(马上获取bean);//从容器中获取 对象// 装备对象 XX XXX1 XX2 xx3User user (User) context.getBean(user2);//System.out.println(21:user);System.out.println(22:context.getBean(user2));//获取接口的类型System.out.println(context.getBean(IUserService.class));context.close();//关闭容器 此时会调用销毁的方法} }3.3 Bean对象创建的4种方式 3.3.1 构造方法创建 使用构造方法创建bean对象是spring默认的创建方式。 !-- 使用构造方法创建对象 -- bean iduser classcom.bjpowernode.domian.User /3.3.2 静态工厂创建 !-- 使用静态工厂创建对象 -- !--id : bean 的唯一标识class : 工厂类factory-method : 工厂方法-- bean iduser2 classcom.bjpowernode.factory.UserStaticFactory factory-methodgetObj /package com.bjpowernode.factory;import com.bjpowernode.domian.User;public class UserStaticFactory {/*** 静态工厂中用于创建对象的方法* return*/public static User getObj(){System.out.println(静态工厂中 创建对象的方法 执行了);return new User();} } 3.3.3 非静态工厂创建 !--非静态工厂创建对象在非静态工厂中创建对象的方法是非静态方法。非静态方法的执行首先需要该类对象注意 使用非静态工厂创建对象首先需要创建工厂类对象 -- !-- 工厂类对象 -- bean iduserFactory classcom.bjpowernode.factory.UserFactory / !-- 使用非静态工厂创建对象 -- !--factory-bean : 非静态工厂对象factory-method : 创建对象的非静态方法 -- bean iduser3 factory-beanuserFactory factory-methodgetObj /package com.bjpowernode.factory;import com.bjpowernode.domian.User;public class UserFactory {/*** 工厂中用于创建对象的方法* return*/public User getObj(){System.out.println(非静态工厂中创建对象的方法 执行了);return new User();} } 3.3.4 注解创建 Spring为简化对象的创建方式提供了注解。 3.3.4.1 组件注解 3.3.4.1.1 Component(“bs”) 表示该类为一个被Spring管理的组件。但是由于在开发中为了让代码的可读性更高。 Spring基于分层思想将需要创建的组件分为以下几类 3.3.4.1.2 Controller Controller注解标识该类是controller层的类。并且注意在使用SpringMVC时所有的Constroller必须使用Controller注解。 3.3.4.1.3 Service Service注解标识该类是业务层的类。 3.3.4.1.4 Respository Respository注解标识该类是操作数据层的类。 注意 以上注解是Spring中定义的创建对象的注解都可以创建对象如果该类有明确的作用有自己所属的层则建议使用相应的注解如果实在无法区分该类所属层可以使用Component注解。 3.3.4.2 注解使用步骤 3.3.4.2.1 开启组件扫描 在spring的核心配置文件中开启注解扫描让Spring将被注解修饰的类创建对相关。 xml头部 xmlns:context“http://www.springframework.org/schema/context” http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd !--开启组件扫描-- context:component-scan base-packagecom.bjpowernode.* / 3.3.4.2.2 添加注解 package com.bjpowernode.domian;import org.springframework.stereotype.Component; Component public class Person {public Person(){System.out.println(Person的构造方法.........);} }3.3.5 什么时候使用XML配置和注解 能使用注解时就使用了注解注解非常方便。但是在第三方的类中是无法使用注解的。因为无法在别人提供的源码上加上Spring注解此时只能使用XML配置的形式配置第三方类的Bean信息。 3.4 IOC属性注入的3种方式 为对象属性设置值就是属性注入。 3.4.1 构造方法属性注入:DI(依赖注入给对象的属性赋值) ?xml version1.0 encodingUTF-8? beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd!-- 无参构造方法 --bean classcom.bjpowernode.domain.User /!--有参数的构造方法此时是2个参数的构造方法index : 参数下标 从 0开始value : 属性的值--bean iduser2 classcom.bjpowernode.domain.User constructor-arg index0 value1001 /constructor-arg index1 value韩梅梅 //bean!-- 有参数的构造方法使用index下标查找 属性 存在问题 都只有一个参数 则默认使用后面的构造方法可以使用 type 指定参数的类型更推荐 使用name属性 name表示构造器中参数的名称--bean iduser3 classcom.bjpowernode.domain.Userconstructor-arg index0 value1001 typejava.lang.Integer //beanbean iduser4 classcom.bjpowernode.domain.Userconstructor-arg namename value韩梅梅 //bean /beanspackage com.bjpowernode.domain;public class User {/*** id 属性*/private Integer id;/*** name 属性*/private String name;public User(){System.out.println(无参数构造方法);}public User(Integer id) {System.out.println(id参数方法);this.id id;}public User(String name) {System.out.println(name参数构造方法);this.name name;}public User(Integer id, String name) {System.out.println(id,name参数构造方法);this.id id;this.name name;}public Integer getId() {return id;}public void setId(Integer id) {this.id id;}public String getName() {return name;}public void setName(String name) {this.name name;} } 3.4.2 set方法属性注入 ?xml version1.0 encodingUTF-8? beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd!--使用set方法进行属性注入property 表示属性name : 表示属性对应的set方法名,去掉set前缀,首字母小写。并不是真正的属性名--bean iddg classcom.powernode.pojo.Dogproperty namesonListlistvalue小黑/valuevalue小白/valuevalue小花/value/list/propertyproperty namewifeListsetvalue小翠儿/valuevalue如花/value/set/propertyproperty namefriendMapmapentry keyuName1 value土狗/entryentry keyuName2 value泰迪/entryentry keyuName3 value-refu1/entry/map/propertyproperty namepropspropsprop keystrain土狗/propprop keyage15/propprop keygender公/prop/props/property /bean/beans 3.4.3 注解属性注入 在spring中为了简化属性的注入Spring提供注解Autowired,Spring会自动从IOC容器中为这个属性查找相应类型的值进行注入。 开启包的注解扫描 context:component-scan base-package“com.*” / 使用注解 package com.bjpowernode.domain;import org.springframework.beans.factory.annotation.Autowired;import java.util.Date; public class Student {public Integer id;public String name;Autowired //使用注解自动注入//User 对象public User user;public void setStudentId(Integer id) {System.out.println(set方法被调用了............);this.id id;}/* public void setUser(User user) {this.user user;}*/ }注意 在使用自动注入时可以在bean标签上配置autowire但是此时必须有该属性的set方法Autowired注解是不需要set方法的。 如果是在xml中注入对象值使用ref属性。value属性只支持boolean,数字字符串等。 3.5 常见类型的属性注入 在Spring中提供了丰富的标签进行各种属性的注入。常见的类型 数字、字符串、boolean、数组、set、list、map、properties。 package com.bjpowernode.domain;import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set;public class Person {private Integer id;private String name;private boolean sex;// true 男 false 女private String[] likes;//爱好private SetString girlFriends; //女朋友private ListDream dreams;//梦想private MapString,String house; //房子private Properties properties; //配置文件属性public Integer getId() {return id;}public void setId(Integer id) {this.id id;}public String getName() {return name;}public void setName(String name) {this.name name;}public boolean getSex() {return sex;}public void setSex(boolean sex) {this.sex sex;}public String[] getLikes() {return likes;}public void setLikes(String[] likes) {this.likes likes;}public SetString getGirlFriends() {return girlFriends;}public void setGirlFriends(SetString girlFriends) {this.girlFriends girlFriends;}public ListDream getDreams() {return dreams;}public void setDreams(ListDream dreams) {this.dreams dreams;}public MapString, String getHouse() {return house;}public void setHouse(MapString, String house) {this.house house;}public Properties getProperties() {return properties;}public void setProperties(Properties properties) {this.properties properties;} }package com.bjpowernode.domain;public class Dream {private String title;public String getTitle() {return title;}public void setTitle(String title) {this.title title;} }?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/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd!-- 简单的属性注入 基本数据类型 string --bean idperson1 classcom.bjpowernode.domain.Person !-- Integer 类型的属性注入 --property nameid value1001 /!-- String 类型的属性注入 --property namename value佚名 /!-- boolean 属性注入 --property namesex valuetrue //bean!-- 数组类型 --bean idperson2 classcom.bjpowernode.domain.Person property namelikes arrayvalue足球/valuevalue篮球/valuevalue羽毛球/value/array/property/bean!-- set 类型注入 --bean idperson3 classcom.bjpowernode.domain.Person property namegirlFriends setvalue韩梅梅/valuevalueLucy/valuevalueLucy/valuevalueRose/value/set/property/beanbean iddream1 classcom.bjpowernode.domain.Dreamproperty nametitle value数钱数到手抽筋 //bean!-- list 类型 --bean idperson4 classcom.bjpowernode.domain.Person property namedreams listbean classcom.bjpowernode.domain.Dreamproperty nametitle value解放全人类 //beanbean classcom.bjpowernode.domain.Dreamproperty nametitle value世界和平 //beanref beandream1//list/property/bean!-- map结构 --bean idperson5 classcom.bjpowernode.domain.Person property namehouse mapentry keywh value江滩 /entry keybj value后海 /entry keyhz value西湖 //map/property/bean!-- properties --bean idperson6 classcom.bjpowernode.domain.Person property nameproperties propsprop keydriver驱动/propprop keyurlurl/prop/props/property/bean /beanspackage com.bjpowernode.test;import com.bjpowernode.domain.Dream; import com.bjpowernode.domain.Person; import com.bjpowernode.domain.Student; import com.bjpowernode.domain.User; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;import java.util.Arrays; import java.util.List; import java.util.Properties;public class Test {public static void main(String[] args) {ApplicationContext context new ClassPathXmlApplicationContext(spring-context.xml);Person person1 (Person) context.getBean(person1);System.out.println(person1.getId() person1.getName() person1.getSex() );Person person2 (Person) context.getBean(person2);String[] likes person2.getLikes();System.out.println(Arrays.asList(likes));Person person3 (Person) context.getBean(person3);System.out.println(person3.getGirlFriends());Person person4 (Person) context.getBean(person4);ListDream dreams person4.getDreams();System.out.println(dreams.get(0).getTitle());System.out.println(dreams.get(1).getTitle());System.out.println(dreams.get(2).getTitle());Person person5 (Person) context.getBean(person5);System.out.println(person5.getHouse());Person person6 (Person) context.getBean(person6);Properties properties person6.getProperties();System.out.println(properties.getProperty(driver));System.out.println(properties.getProperty(url));} }3.6 使用IOC容器改造传统项目 3.6.1 xml配置版 3.6.1.1 创建项目并加入依赖 !--依赖-- dependencies!--引入spring的context依赖可以传递出aop beans core expression--dependencygroupIdorg.springframework/groupIdartifactIdspring-context/artifactIdversion5.3.4/version/dependency /dependencies3.6.1.2 项目结构 3.6.1.3 配置文件 ?xml version1.0 encodingUTF-8? beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd!-- 声明 com.bjpowernode.dao 对象 --bean iduserDao classcom.bjpowernode.dao.UserDao /!-- 声明service 对象 --bean iduserService classcom.bjpowernode.service.impl.UserServiceImpl autowirebyType!-- 使用自动装配 则不需要 声明属性注入 但是要有set方法 --!--property nameuserDao refuserDao /--/bean!-- 声明controller --bean iduserController classcom.bjpowernode.controller.UserController autowirebyType!-- 使用自动装配 则不需要 声明属性注入 但是要有set方法--!--property nameuserService refuserService/--/bean /beans 3.6.1.4 controller package com.bjpowernode.controller;import com.bjpowernode.service.IUserService;public class UserController {private IUserService userService;public void register(){System.out.println(控制层的 register 方法);userService.register();}public void setUserService(IUserService userService) {this.userService userService;} } 3.6.1.5 dao package com.bjpowernode.dao; public class UserDao {public void add(){System.out.println(进行数据库数据新增操作);} } 3.6.1.6 service package com.bjpowernode.service;public interface IUserService {/*** 注册接口*/public void register(); }package com.bjpowernode.service.impl;import com.bjpowernode.dao.UserDao; import com.bjpowernode.service.IUserService;public class UserServiceImpl implements IUserService {/*** com.bjpowernode.dao 层 属性*/private UserDao userDao;Overridepublic void register() {System.out.println(com.bjpowernode.service 的 register );userDao.add();}/*** 使用set方法 是为了自动装配 或者进行set 属性设置* param userDao*/public void setUserDao(UserDao userDao) {this.userDao userDao;} } 3.6.1.7 test package com.bjpowernode; import com.bjpowernode.controller.UserController; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;public class Test {public static void main(String[] args) {ApplicationContext context new ClassPathXmlApplicationContext(spring-context.xml);UserController bean context.getBean(UserController.class);bean.register();} }3.6.2 注解版 3.6.2.1 配置文件 ?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/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd!-- 开启组件扫描 --context:component-scan base-packagecom.* / /beans 3.6.2.2 controller package com.bjpowernode.controller;import com.bjpowernode.service.IUserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller;Controller public class UserController {Autowiredprivate IUserService userService;public void register(){System.out.println(控制层的 register 方法);userService.register();} } 3.6.2.3 dao package com.bjpowernode.dao;import org.springframework.stereotype.Repository;Repository public class UserDao {public void add(){System.out.println(进行数据库数据新增操作);} } 3.6.2.4 service package com.bjpowernode.service;public interface IUserService {/*** 注册接口*/public void register(); }package com.bjpowernode.service.impl;import com.bjpowernode.dao.UserDao; import com.bjpowernode.service.IUserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service;Service public class UserServiceImpl implements IUserService {/*** com.bjpowernode.dao 层 属性*/Autowiredprivate UserDao userDao;Overridepublic void register() {System.out.println(com.bjpowernode.service 的 register );userDao.add();} } 3.6.2.5 test package com.bjpowernode.test;import com.bjpowernode.controller.UserController; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;public class Test {public static void main(String[] args) {ApplicationContext context new ClassPathXmlApplicationContext(spring-context.xml);//UserController bean context.getBean(UserController.class);//bean.register();//程序员自己创建的对象 不在IOC 自己容器中//new UserController().register();} }4.AOP com.powernode.aadenglu Login: login():登录方法 com.powernode.anquan Security: isSecurity():检测操作环境是否安全 com.powernode.bmapper CBCBankMapper(核心类): selectMoney() updateMoney() updateInvest() update2Tel() com.powernode.crizhi Logger: log():记录用户操作细节 com.powernode.dqinli Clean :cleanResource():清理缓存 Expt: handExpt() 4.1 AOP简介面向切面(面向组件) DefaultAopProxyFactory 代理 静态代理 静态代理每个被代理类都需要创建对应的代理类。随着程序的扩展代理类也会增多臃肿,维护量变多,为了解决这个问题Java中提供了动态代理技术开发者不需要自己定义代理类代理类由JDK动态的创建开发只需要指定被代理的类即可。 切面(aspect)除了核心类以外的其他类称之为切面 通知(advisor):切面中的方法称之为通知 核心类一个项目中不能省略的模块类 核心方法核心类中的方法称之为核心方法 连接点核心类中的某一个方法 切入点(pointcut)某个包下的某个类下的某一批方法 代理(proxy)将多个切面与核心类组合在一起形成一个新的类这个类称之为代理类 织入(weaver)书写代理类的过程称之为织入 4.2 动态代理 4.2.1 JDK动态代理 4.2.1.1 Proxy 该类提供了方法创建代理类和代理类的对象的方法 创建一个代理类并返回代理类对象 static Object newProxyInstance(ClassLoader loader, Class?[] interfaces, InvocationHandler h) loader 类加载器指定类加载器是为了精确的定位类 interfaces 接口Class类使用JDK的反射必须要有接口 h InvocationHandler 代理的处理器每个代理类都有一个关联的处理器 4.2.1.2 InvocationHandler 是每个代理类对应的处理器 Object 方法调用的返回值可以作为被代理的方法调用的返回值 proxy 代理类对象 method 目标类中被代理的方法 args : 目标类中被代理的方法的运行参数 Object invoke(Object proxy,Method method,Object[] args) 4.2.1.3 代码示例 4.2.1.3.1 目标类接口 package com.bjpowernode.proxy.demo02;/*** Description: 目标类接口* author: Mr.T* date 2020-09-27 10:38*/ public interface ITargetClass {/*** 房子出租* param m*/void rent(int m); }4.2.1.3.2 目标类 package com.bjpowernode.proxy.demo02;/*** Description: 目标类* author: Mr.T* date 2020-09-27 10:39*/ public class TargetClass implements ITargetClass {Overridepublic void rent(int m) {System.out.println(出租的金额为 m);} }4.2.1.3.3 代理类处理器 package com.bjpowernode.proxy.demo02;import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method;/*** Description: 代理的处理器* 处理器会被绑定一个代理* 帮助代理调用目标方法* author: Mr.T* date 2020-09-27 10:40*/ public class ProxyHanlder implements InvocationHandler {/*** 目标方法类的对象*/private Object targetObj;public ProxyHanlder(Object targetObj){this.targetObj targetObj;}/**** param proxy 生成的代理类的对象* param method 目标类中被代理的方法* param args 目标类中被代理的方法实际参数* return 可以当做目标方法的返回值* throws Throwable*/Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {//使用反射调用 目标类中的方法Object obj method.invoke(targetObj, args);return obj;} }4.2.1.3.4 测试类 package com.bjpowernode.proxy.demo02;import java.lang.reflect.Proxy;/*** Description: TODO* author: Mr.T* date 2020-09-27 10:45*/ public class Test {public static void main(String[] args) {System.getProperties().put(sun.misc.ProxyGenerator.saveGeneratedFiles,true);//创建了目标类对象ITargetClass targetClass new TargetClass();//创建处理器ProxyHanlder proxyHanlder new ProxyHanlder(targetClass);//创建具体的代理类和对象 具体产生的代理类 会实现 接口 所以能够转化为 接口类型ITargetClass proxy (ITargetClass) Proxy.newProxyInstance(Test.class.getClassLoader(), new Class[]{ITargetClass.class}, proxyHanlder);// 调用代理类中 rent方法 $proxy0proxy.rent(100);} } 4.2.1.3.5 生成代理类源码 package com.bjpowernode.proxy.demo02;import java.lang.reflect.InvocationHandler; import java.lang.reflect.UndeclaredThrowableException;/*** Description: 动态代理生成的代理类* Proxy : JDK中所有生成的代理的父类* ITargetClass : 指定被代理类的接口** author: Mr.T* date 2020-09-27 10:59*/ public final class $Proxy0 extends Proxy implements ITargetClass {private static Method m0; //hashCode 方法private static Method m1; // equalsprivate static Method m2; //toStringprivate static Method m3; // rent 方法 被代理的方法static {try {$Proxy0.m0 Class.forName(java.lang.Object).getMethod(hashCode, (Class?[])new Class[0]);$Proxy0.m1 Class.forName(java.lang.Object).getMethod(equals, Class.forName(java.lang.Object));$Proxy0.m2 Class.forName(java.lang.Object).getMethod(toString, (Class?[])new Class[0]);$Proxy0.m3 Class.forName(com.bjpowernode.proxy.demo02.ITargetClass).getMethod(rent, Integer.TYPE);}catch (NoSuchMethodException ex) {throw new NoSuchMethodError(ex.getMessage());}catch (ClassNotFoundException ex2) {throw new NoClassDefFoundError(ex2.getMessage());}}/*** invocationHandler 就是定义的 invocationHandler* param invocationHandler*/public $Proxy0(final InvocationHandler invocationHandler) {super(invocationHandler); //Proxy(InvocationHandler invocationHandler) -- 为父类中 InvocationHandler 赋值//当前类中 InvocationHandler 对象 且有值/*Proxy(InvocationHandler h) {Objects.requireNonNull(h);this.h h;}* */}public final boolean equals(final Object o) {try {return (boolean)super.h.invoke(this, $Proxy0.m1, new Object[] { o });}catch (Error | RuntimeException error) {throw;}catch (Throwable t) {throw new UndeclaredThrowableException(t);}}public final String toString() {try {return (String)super.h.invoke(this, $Proxy0.m2, null);}catch (Error | RuntimeException error) {throw;}catch (Throwable t) {throw new UndeclaredThrowableException(t);}}public final void rent(final int n) {try {//super.h this.h --- 自定义的 ProxyHanlder//调用自定义的ProxyHanlder 中的invoke方法 : $Proxy0 对象//$Proxy0.m3 rent 方法//new Object[] { n } 传入的参数super.h.invoke(this, $Proxy0.m3, new Object[] { n });}catch (Error | RuntimeException error) {throw;}catch (Throwable t) {throw new UndeclaredThrowableException(t);}}public final int hashCode() {try {return (int)super.h.invoke(this, $Proxy0.m0, null);}catch (Error | RuntimeException error) {throw;}catch (Throwable t) {throw new UndeclaredThrowableException(t);}} }4.2.1.3.6 JDK动态代理的不足 在JDK中使用动态代理必须有类的接口。因为生成的代理需要实现这个接口这样我们生成的代理类对象才能转化为代理目标的接口对象然后根据接口中的方法调用处理器中invoke方法。 4.2.2 Cglib动态代理 为了弥补JDK动态代理的不足第三方组织封装一套工具包cglib的工具包这套包不基于接口基于父子继承通过重写的形式扩展方法但是这个子类工具自动生成的。 早期Cglib动态代理性能相于JDK的动态代理高一些。JDK进行一些列优化目前Spring默认使用的动态代理JDK也支持Cglib。 4.2.2.1 Cglib动态代理的使用 4.2.2.1.1 MethodInterceptor cglib中提供的对方法执行拦截的接口。其中intercept是对具体方法进行拦截处理的方法。 public Object intercept(Object obj, java.lang.reflect.Method method, Object[] args, MethodProxy proxy)Object 方法执行返回的结果 obj 增强类的对象 method 目标方法 proxy 用于回调的方法的对象 4.2.2.1.2 代码示例 4.2.2.1.2.1 导入jar包 !-- 引入cglib 的jar 包-- dependencygroupIdcglib/groupIdartifactIdcglib/artifactIdversion3.3.0/version /dependency4.2.2.1.2.2 创建被代理目标类 package com.bjpowernode.proxy.demo03;/*** Description: 被代理的目标类* author: Mr.T* date 2020-09-27 14:13*/ public class TargetClass {public void rent(){System.out.println(目标类中的出租方法);} } 4.2.2.1.2.3 方法拦截器 package com.bjpowernode.proxy.demo03;import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy;import java.lang.reflect.Method;/*** Description: 方法执行的拦截器* author: Mr.T* date 2020-09-27 14:20*/ public class MyMethodInteceptor implements MethodInterceptor {/*** 进行具体的拦截的方法* param obj 被代理类的对象* param method 被代理的目标方法* param args 实际运行的参数* param proxy 代理类对象* return* throws Throwable*/Overridepublic Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {System.out.println(前置增强);//代理 调用父类中的方法Object o proxy.invokeSuper(obj, args);System.out.println(intercept 执行了);//执行了System.out.println(后置增强);return o ;} } 4.2.2.1.2.4 测试类 package com.bjpowernode.proxy.demo03;import net.sf.cglib.proxy.Enhancer;/*** Description: TODO* author: Mr.T* date 2020-09-27 14:21*/ public class Test {public static void main(String[] args) {//增强类工具 可以创建代理类对象Enhancer enhancer new Enhancer();enhancer.setSuperclass(TargetClass.class);//设置调用时 回调enhancer.setCallback(new MyMethodInteceptor());//创建代理类对象TargetClass proxy (TargetClass) enhancer.create();proxy.rent();} } 4.2.2.2 动态代理的不足 不论是JDK的动态代理还是第三方cglib动态代理都需要开发者编写代码处理程序。程序结构基本上大同小异重复造轮子。基于这样的情况在Spring中提供了2种方式xml配置形式和注解形式使用动态代理。这种模式就是Spring Aop技术。其底层依然是动态代理。 4.3 Spring的AOP配置 在Spring中AOP的配置主要分为2类xml配置和注解配置 XML配置也分为两种一种Spring的原生支持一种是Spring的aspects这个相关的框架。 4.3.1 AOP的相关概念 连接点(JoinPoint)所谓连接点是指那些被拦截的点而spring中这些点就是指方法因为spring只支持方法类型的连接点。 切入点(PointCut)所谓切入点就是指我们要对那些JoinPoint进行拦截的定义指的是具体的拦截的位置 增强/通知(Advice) : 增强就是对具体的连接点进行扩展的功能。由于一般对方法进行增强分为在方法前执行或者方法后或者发生异常执行等等所以增强被分为前置增强(前置通知)、后置增强(后置通知)、环绕通知(环绕增强)、异常增强异常通知 引介(Introduction)引介是一种特殊的Advice在不修改代码的前提下引介可以在运行期为类动态的添加一些方法或Field. 目标(Target) :被代理的类(需要增强类) 织入(Weaving) :把Advice应用到Target的过程 代理(Proxy):使用AOP配置后产生的代理类 切面(Aspect):切点和增强整合形成了切面 4.3.2 Spring自身AOP具体配置 4.3.2.1 引入aop相关jar包 ?xml version1.0 encodingUTF-8? project xmlnshttp://maven.apache.org/POM/4.0.0xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdmodelVersion4.0.0/modelVersiongroupIdorg.example/groupIdartifactId02-spring-aop01/artifactIdversion1.0-SNAPSHOT/versionpropertiesproject.build.sourceEncodingUTF-8/project.build.sourceEncodingmaven.compiler.source1.8/maven.compiler.sourcemaven.compiler.target1.8/maven.compiler.targetspring.version5.2.0.RELEASE/spring.version/propertiesdependenciesdependencygroupIdorg.springframework/groupIdartifactIdspring-context/artifactIdversion${spring.version}/version/dependencydependencygroupIdorg.springframework/groupIdartifactIdspring-context-support/artifactIdversion${spring.version}/version/dependencydependencygroupIdorg.springframework/groupIdartifactIdspring-aspects/artifactIdversion${spring.version}/version/dependency/dependencies/project 4.3.2.2 定义增强类 4.3.2.2.1 前置增强-MethodBeforeAdvice package com.bjpowernode.advice;import org.springframework.aop.MethodBeforeAdvice;import java.lang.reflect.Method;/*** Description: spring 规定的增强方法接口* author: Mr.T* date 2020-09-27 15:42*/ public class MyBeforeAdvice implements MethodBeforeAdvice {/**** param method 目标方法* param args 实际运行的参数* param target 目标类对象* throws Throwable*/Overridepublic void before(Method method, Object[] args, Object target) throws Throwable {System.out.println(前置增强的方法);} }4.3.2.2.2 后置增强-AfterReturningAdvice package com.bjpowernode.advice;import org.springframework.aop.AfterReturningAdvice;import java.lang.reflect.Method;/*** Description: 后置增强接口* author: Mr.T* date 2020-09-27 15:55*/ public class MyAfterAdvice implements AfterReturningAdvice {/**** param returnValue 被增强的方法运行后返回的数据* param method 被增强的方法* param args 方法运行的参数* param target 目标类对象* throws Throwable*/Overridepublic void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {System.out.println(后置增强方法);} }4.3.2.2.3 环绕增强-MethodInterceptor package com.bjpowernode.advice;import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation;/*** Description: 环绕增强* author: Mr.T* date 2020-09-27 16:04*/ public class MyAroundAdvice implements MethodInterceptor {Overridepublic Object invoke(MethodInvocation invocation) throws Throwable {System.out.println(前置增强);Object rs invocation.proceed();//调用 目标方法System.out.println(后置增强);return rs;} } 4.3.2.2.4 异常增强-ThrowsAdvice 异常增强中的增强方法必须叫afterThrowing并且必须定义参数接收发生的异常信息。 package com.bjpowernode.advice;import org.springframework.aop.ThrowsAdvice;/*** Description: 异常增强类* author: Mr.T* date 2020-09-27 16:12*/ public class MyExceptionAdvice implements ThrowsAdvice {public void afterThrowing(Exception ex){System.out.println(异常增强的方法!!!!!!);} } 4.3.2.3 目标类 package com.bjpowernode;public interface ITargetClass {/*** 待增强的目标方法*/void targetMethod();/*** 待增强的方法* param msg* return*/String afterTargetMethod(String msg);/*** 环绕增强的方法*/void aroundTargetMethod();/*** 执行会发生异常*/void runException(); }package com.bjpowernode.impl;import com.bjpowernode.ITargetClass;/*** Description: 目标类* author: Mr.T* date 2020-09-27 15:38*/ public class TargetClassImpl implements ITargetClass {Overridepublic void targetMethod() {System.out.println(待增强的目标方法);}Overridepublic String afterTargetMethod(String msg) {System.out.println(待增强的目标方法 --- afterTargetMethod);return 被增强的方法的返回值;}public void aroundTargetMethod() {System.out.println(待增强的目标方法 --- aroundTargetMethod);}/*** 发生异常*/public void runException() {System.out.println(待增强的目标方法 --- runException);int m 0;int n 100/m;}} 4.3.2.4 aop配置 ?xml version1.0 encodingUTF-8? beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xmlns:aophttp://www.springframework.org/schema/aopxsi:schemaLocationhttp://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd!-- 定义目标类对象 --bean idtargetClass classcom.bjpowernode.impl.TargetClassImpl /!-- 定义增强类对象 前置增强类 --bean idmyBeforeAdvice classcom.bjpowernode.advice.MyBeforeAdvice /!-- 定义增强类对象 后置增强 --bean idmyAfterAdvice classcom.bjpowernode.advice.MyAfterAdvice /!-- 定义增强类 环绕增强 --bean idmyAroundAdvice classcom.bjpowernode.advice.MyAroundAdvice /!-- 定义增强类 异常增强类 --bean idmyExceptionAdvice classcom.bjpowernode.advice.MyExceptionAdvice /!-- 进行织入 --aop:config!--id : 连接点的唯一标识expression : 连接点的表达式execution(* 包名.类名.方法名(..))* 指任意字符.. 表示参数可以是任意个--aop:pointcut idbeforePoint expressionexecution(* com.bjpowernode.impl.TargetClassImpl.targetMethod(..))/!-- 后置增强的切点 --aop:pointcut idafterPoint expressionexecution(* com.bjpowernode.impl.TargetClassImpl.afterTargetMethod(..))/!-- 环绕增强的切点 --aop:pointcut idaroundPoint expressionexecution(* com.bjpowernode.impl.TargetClassImpl.aroundTargetMethod(..))/!-- 异常增强的切点 --aop:pointcut idexceptionPoint expressionexecution(* com.bjpowernode.impl.TargetClassImpl.runException(..))/!--织入将增强和连接点 结合--aop:advisor advice-refmyBeforeAdvice pointcut-refbeforePoint /!-- 织入后置增强的织入--aop:advisor advice-refmyAfterAdvice pointcut-refafterPoint /!--织入环绕增强的织入--aop:advisor advice-refmyAroundAdvice pointcut-refaroundPoint /!--织入异常增强的织入--aop:advisor advice-refmyExceptionAdvice pointcut-refexceptionPoint //aop:config/beans4.3.2.5 测试类 package com.bjpowernode;import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;public class Test {public static void main(String[] args) {ApplicationContext context new ClassPathXmlApplicationContext(spring-context.xml);ITargetClass targetClass context.getBean(ITargetClass.class);targetClass.runException();} } 4.3.3 AspectJ框架AOP配置 在原生的spring中每种增强都需要单独定义一个类实现相应的接口。增强类本身就更庞大而且方法的名称是固定的。基于这种情况AspectJ提供了相对更加灵活的方式。 在AspectJ中只需要定义一个增强类即可并且方法的名称可以任意定义。 4.3.3.1 引入相关jar ?xml version1.0 encodingUTF-8? project xmlnshttp://maven.apache.org/POM/4.0.0xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdmodelVersion4.0.0/modelVersiongroupIdorg.example/groupIdartifactId02-spring-aop02/artifactIdversion1.0-SNAPSHOT/versionpropertiesproject.build.sourceEncodingUTF-8/project.build.sourceEncodingmaven.compiler.source1.8/maven.compiler.sourcemaven.compiler.target1.8/maven.compiler.targetspring.version5.2.0.RELEASE/spring.version/propertiesdependenciesdependencygroupIdorg.springframework/groupIdartifactIdspring-context/artifactIdversion${spring.version}/version/dependencydependencygroupIdorg.springframework/groupIdartifactIdspring-context-support/artifactIdversion${spring.version}/version/dependencydependencygroupIdorg.springframework/groupIdartifactIdspring-aspects/artifactIdversion${spring.version}/version/dependency/dependencies /project 4.3.3.2 编写增强类 package com.bjpowernode.advice;import org.aopalliance.intercept.Invocation; import org.aopalliance.intercept.MethodInvocation; import org.aspectj.lang.ProceedingJoinPoint;public class MyAdvice {public void beforAdvice(){System.out.println(前置增强的方法);}public void afterAdvice(String name,String rs){System.out.println(后置增强的方法);}public void aroundAdvice(ProceedingJoinPoint joinPoint){System.out.println(前置增强);try {joinPoint.proceed();} catch (Throwable throwable) {throwable.printStackTrace();}System.out.println(后置增强);}/*** 异常增强* param exception*/public void exceptionAdvice(Exception exception){System.out.println(异常增强!);} } 4.3.3.3 编写目标类 package com.bjpowernode;public interface ITargetClass {/*** 前置增强的方法*/void beforeMethod();/*** 后置增强的方法*/String afterMethod(String name1);/*** 环绕增强的方法*/void aroundMethod();/*** 异常增的方法*/void runExceptionMethod(); }package com.bjpowernode.impl;import com.bjpowernode.ITargetClass;public class TargetClassImpl implements ITargetClass {Overridepublic void beforeMethod() {System.out.println(待前置增强--------beforeMethod);}Overridepublic String afterMethod(String name) {System.out.println(待后置增强--------afterMethod);return 韩梅梅;}Overridepublic void aroundMethod() {System.out.println(待环绕增强--------aroundMethod);}Overridepublic void runExceptionMethod() {System.out.println(待异常增强--------runExceptionMethod);int m 0;int n 100/m;} } 4.3.3.4 配置AspectJ的增强配置 ?xml version1.0 encodingUTF-8? beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xmlns:aophttp://www.springframework.org/schema/aopxsi:schemaLocationhttp://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd!-- 定义增强的目标类对象 --bean idtargetClass classcom.bjpowernode.impl.TargetClassImpl /!-- 定义增强类的对象 --bean idmyAdvice classcom.bjpowernode.advice.MyAdvice /!-- 进行AOP配置 --aop:config!-- 前置切点 --!--aop:before : aspectJ中 前置增强的配置method : 当前增强类中前置增强的方法 方法名pointcut-ref : 增强连接点--aop:pointcut idbeforPoint expressionexecution(* com.bjpowernode.impl.TargetClassImpl.beforeMethod(..)) /!-- 后置切点 --!-- args 配置被增强的方法的参数名称 --aop:pointcut idafterPoint expressionexecution(* com.bjpowernode.impl.TargetClassImpl.afterMethod(..)) and args(name) /!-- 环绕切点 --aop:pointcut idaroundPoint expressionexecution(* com.bjpowernode.impl.TargetClassImpl.aroundMethod(..)) /!-- 异常切点 --aop:pointcut idexceptionPoint expressionexecution(* com.bjpowernode.impl.TargetClassImpl.runExceptionMethod(..)) /aop:aspect refmyAdvice!-- aop:before methodbeforAdvice pointcut-refbeforPoint /--!--arg-names :后置增强中增强的方法的参数名称注意 name 也是被增强的方法的参数名称 参数名称要一致returning 返回结果的参数名称--aop:after-returning methodafterAdvice pointcut-refafterPoint arg-namesname,rs returningrs /!--aop:around methodaroundAdvice pointcut-refaroundPoint /--!--throwing : 接收异常参数的名称--aop:after-throwing methodexceptionAdvice pointcut-refexceptionPoint throwingexception //aop:aspect/aop:config/beans 4.3.3.5 进行测试 package com.bjpowernode;import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;public class Test {public static void main(String[] args) {ApplicationContext context new ClassPathXmlApplicationContext(spring-context.xml);ITargetClass bean context.getBean(ITargetClass.class);bean.runExceptionMethod();} }4.3.4 AspectJ的AOP注解方式 4.3.4.1 引入相关jar包 ?xml version1.0 encodingUTF-8? project xmlnshttp://maven.apache.org/POM/4.0.0xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdmodelVersion4.0.0/modelVersiongroupIdorg.example/groupIdartifactId02-spring-aop3/artifactIdversion1.0-SNAPSHOT/versionpropertiesproject.build.sourceEncodingUTF-8/project.build.sourceEncodingmaven.compiler.source1.8/maven.compiler.sourcemaven.compiler.target1.8/maven.compiler.targetspring.version5.2.0.RELEASE/spring.version/propertiesdependenciesdependencygroupIdorg.springframework/groupIdartifactIdspring-context/artifactIdversion${spring.version}/version/dependencydependencygroupIdorg.springframework/groupIdartifactIdspring-context-support/artifactIdversion${spring.version}/version/dependencydependencygroupIdorg.springframework/groupIdartifactIdspring-aspects/artifactIdversion${spring.version}/version/dependency/dependencies /project4.3.4.2 定义增强类 package com.bjpowernode.advice;import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.*; import org.springframework.stereotype.Component;Aspect Component public class MyAdvice {Before(value execution(* com.bjpowernode.impl.TargetClassImpl.beforeMethod(..)))public void beforAdvice(){System.out.println(前置增强的方法);}/**args 被增强的方法的参数名称* argNames 增强方法的参数名称* 参数名称必须一致* returning 参数名称* */AfterReturning(valueexecution(* com.bjpowernode.impl.TargetClassImpl.afterMethod(..)) args(name),argNames name,rs ,returning rs )public void afterAdvice(String name,String rs){System.out.println(后置增强的方法);}Around(valueexecution(* com.bjpowernode.impl.TargetClassImpl.aroundMethod(..)))public void aroundAdvice(ProceedingJoinPoint joinPoint){System.out.println(前置增强);try {joinPoint.proceed();} catch (Throwable throwable) {throwable.printStackTrace();}System.out.println(后置增强);}/*** 异常增强* param exception*/AfterThrowing(valueexecution(* com.bjpowernode.impl.TargetClassImpl.runExceptionMethod(..)),throwing exception )public void exceptionAdvice(Exception exception){System.out.println(异常增强!);} } 4.3.4.3 目标类 package com.bjpowernode;public interface ITargetClass {/*** 前置增强的方法*/void beforeMethod();/*** 后置增强的方法*/String afterMethod(String name);/*** 环绕增强的方法*/void aroundMethod();/*** 异常增的方法*/void runExceptionMethod(); }package com.bjpowernode.impl;import com.bjpowernode.ITargetClass; import org.aspectj.lang.annotation.Pointcut; import org.springframework.stereotype.Component;Component public class TargetClassImpl implements ITargetClass {Overridepublic void beforeMethod() {System.out.println(待前置增强--------beforeMethod);}Overridepublic String afterMethod(String name) {System.out.println(待后置增强--------afterMethod);return 韩梅梅;}Overridepublic void aroundMethod() {System.out.println(待环绕增强--------aroundMethod);}Overridepublic void runExceptionMethod() {System.out.println(待异常增强--------runExceptionMethod);int m 0;int n 100/m;} } 4.3.4.4 开启相关注解 ?xml version1.0 encodingUTF-8? beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexmlns:contexthttp://www.springframework.org/schema/contextxmlns:aophttp://www.springframework.org/schema/aopxsi:schemaLocationhttp://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd!-- 开启组件扫描 --context:component-scan base-packagecom.* /!-- 开启aspectj 的相关注解 --aop:aspectj-autoproxy proxy-target-classtrue/ /beans4.3.4.5 测试类 package com.bjpowernode;import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;public class Test {public static void main(String[] args) {ApplicationContext context new ClassPathXmlApplicationContext(spring-context.xml);ITargetClass bean context.getBean(ITargetClass.class);bean.runExceptionMethod();} }5.Spring整合Mybatis Spring整合Mybatis就是将Mybatis交给Spring进行管理将Mybatis的SqlSession对象放入IOC容器中并且可以利用自动装配功能为每个数据库操作层注入SqlSession。并且Spring内置可以有代理的可以根据SqlSession对象及数据操作接口创建Mapper接口的代理对象此时Mapper的代理在IOC容器中那么可以将Mapper接口的对象注入到Service中。 5.1 多XML版 使用配置文件版本Mybatis配置文件和Spring配置文件是单独的。 5.1.1 引入相关jar包 5.1.1.1 spring相关jar包 !-- spring相关jar包 开始 -- dependencygroupIdorg.springframework/groupIdartifactIdspring-context/artifactIdversion5.2.0.RELEASE/version /dependency dependencygroupIdorg.springframework/groupIdartifactIdspring-context-support/artifactIdversion5.2.0.RELEASE/version /dependency dependencygroupIdorg.springframework/groupIdartifactIdspring-aspects/artifactIdversion5.2.0.RELEASE/version /dependency dependencygroupIdorg.springframework/groupIdartifactIdspring-jdbc/artifactIdversion5.2.0.RELEASE/version /dependency !-- spring相关jar包 结束 --5.1.1.2 mybatis相关jar包 !-- mybatis核心包 开始-- dependencygroupIdorg.mybatis/groupIdartifactIdmybatis/artifactIdversion3.5.7/version /dependency !-- mybatis核心包 结束--5.1.1.3 数据库相关jar包 !-- mysql jdbc 数据库包 开始 -- dependencygroupIdmysql/groupIdartifactIdmysql-connector-java/artifactIdversion5.1.49/version /dependency !-- mysql jdbc 数据库包 结束 --5.1.1.4 日志相关jar包 !-- 日志相关jar包 开始 -- dependencygroupIdcommons-logging/groupIdartifactIdcommons-logging/artifactIdversion1.2/version /dependency dependencygroupIdlog4j/groupIdartifactIdlog4j/artifactIdversion1.2.17/version /dependency dependencygroupIdorg.apache.logging.log4j/groupIdartifactIdlog4j-core/artifactIdversion2.13.3/version /dependency !-- 日志相关jar包 结束 --5.1.1.5 spring和mybatis整合包 !-- spring和 mybatis 整合包 开始 -- dependencygroupIdorg.mybatis/groupIdartifactIdmybatis-spring/artifactIdversion2.0.4/version /dependency !-- spring和 mybatis 整合包 结束--5.1.1.6 mybatis分页插件包 !-- mybatis分页插件包 开始-- dependencygroupIdcom.github.pagehelper/groupIdartifactIdpagehelper/artifactIdversion5.2.0/version /dependency !-- mybatis分页插件包 结束--5.1.2 相关类 5.1.2.1 domain package com.bjpowernode.domain;public class User {private Integer id;private String username;private String password;private String realname;public Integer getId() {return id;}public void setId(Integer id) {this.id id;}public String getUsername() {return username;}public void setUsername(String username) {this.username username;}public String getPassword() {return password;}public void setPassword(String password) {this.password password;}public String getRealname() {return realname;}public void setRealname(String realname) {this.realname realname;}Overridepublic String toString() {return User{ id id , username username \ , password password \ , realname realname \ };} }5.1.2.2 mapper package com.bjpowernode.mapper;import com.bjpowernode.domain.User; import org.apache.ibatis.annotations.Param;import java.util.List;public interface UserMapper {/*** 根据ID 查询用户* param id* return*/User selectById(Param(id) Integer id);/*** 查询所有* return*/ListUser selectAll(); } 5.1.2.3 service package com.bjpowernode.service;import com.github.pagehelper.PageInfo; import com.bjpowernode.domain.User;public interface IUserService {User queryUser(Integer id);PageInfoUser queryPage(Integer page,Integer limit); }package com.bjpowernode.service.impl;import com.github.pagehelper.Page; import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; import com.bjpowernode.domain.User; import com.bjpowernode.mapper.UserMapper; import com.bjpowernode.service.IUserService;public class UserServiceImpl implements IUserService {private UserMapper userMapper;Overridepublic User queryUser(Integer id) {return userMapper.selectById(id);}Overridepublic PageInfoUser queryPage(Integer page,Integer limit) {PageUser users PageHelper.startPage(page, limit);userMapper.selectAll();return users.toPageInfo();}/*** 使用xml形式注入 mapper* param userMapper*/public void setUserMapper(UserMapper userMapper) {this.userMapper userMapper;} } 5.1.2.4 测试类 package com.bjpowernode;import com.github.pagehelper.PageInfo; import com.bjpowernode.domain.User; import com.bjpowernode.service.IUserService; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;import java.util.List;public class Test {public static void main(String[] args) {ApplicationContext context new ClassPathXmlApplicationContext(spring-context.xml);IUserService bean context.getBean(IUserService.class);PageInfoUser pageInfo bean.queryPage(2, 1);ListUser list pageInfo.getList();for (User user : list) {System.out.println(user);}} } 5.1.3 相关配置文件 5.1.3.1 jdbc配置文件 #数据库连接信息 jdbc.drivercom.mysql.jdbc.Driver jdbc.urljdbc:mysql://localhost:3306/test?useUnicodetrueuseSSLfalsecharacterEncodingUTF8serverTimezoneUTC jdbc.usernameroot jdbc.password123456 5.1.3.2 日志配置文件 # 全局日志配置 log4j.rootLoggerDEBUG, stdout # MyBatis 日志配置 log4j.logger.org.mybatis.example.BlogMapperTRACE # 控制台输出 log4j.appender.stdoutorg.apache.log4j.ConsoleAppender log4j.appender.stdout.layoutorg.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern%5p [%t] - %m%n5.1.3.3 mybatis核心配置文件 ?xml version1.0 encodingUTF-8 ? !DOCTYPE configurationPUBLIC -//mybatis.org//DTD Config 3.0//ENhttp://mybatis.org/dtd/mybatis-3-config.dtd configuration!-- 引入数据库配置文件 --!--properties resourcejdbc.properties /--!-- 全局设置 --settingssetting namelogImpl valueLOG4J//settings!-- 配置类别名 --typeAliasespackage namecom.bjpowernode.domain//typeAliases!-- 配置分页插件 --pluginsplugin interceptorcom.github.pagehelper.PageInterceptor //plugins!-- 数据源环境 -- !-- environments defaultdevenvironment iddevtransactionManager typeJDBC/transactionManagerdataSource typePOOLEDproperty namedriver value${jdbc.driver}/property nameurl value${jdbc.url}/property nameusername value${jdbc.username}/property namepassword value${jdbc.password}//dataSource/environment/environments--!-- 映射文件 --mappersmapper resourcemapper/UserMapper.xml //mappers /configuration5.1.3.4 mybatis映射文件 ?xml version1.0 encodingUTF-8 ? !DOCTYPE mapperPUBLIC -//mybatis.org//DTD Mapper 3.0//ENhttp://mybatis.org/dtd/mybatis-3-mapper.dtd mapper namespacecom.bjpowernode.mapper.UserMapperselect idselectById resultTypecom.bjpowernode.domain.Userselect * from user where id #{id}/selectselect idselectAll resultTypecom.bjpowernode.domain.Userselect * from user/select /mapper5.1.3.5 spring核心配置文件 ?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/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd!--终极目标 为 每个service 注入一个Mapper 对象1. Mapper 对象2. SqlSession 获取3. SqlSession 要根据 SqlSessionFactory 获取4. SqlSessionFactory 要 根据 SqlSessionFactoryBuilder获取5. SqlSessionFactoryBuilder 可以直接创建 此时需要使用IOC容器6. 配置数据源--!--1. 引入jdbc的配置文件 使用配置文件 不是使用系统属性--context:property-placeholder locationjdbc.properties system-properties-modeFALLBACK /!--2. 配置数据源 --bean iddataSource classorg.springframework.jdbc.datasource.DriverManagerDataSourceproperty namedriverClassName value${jdbc.driver}/propertyproperty nameurl value${jdbc.url}/propertyproperty nameusername value${jdbc.username}/propertyproperty namepassword value${jdbc.password}/property/bean!--3. 配置SqlSessionFactoryBean 对象--bean idsqlSessionFactoryBean classorg.mybatis.spring.SqlSessionFactoryBean!-- mybatis 核心配置文件 --property nameconfigLocation valuemybatis.xml /property namedataSource refdataSource //bean!-- 4.扫描所有的Mapper接口 自动创建Mapper的代理对象 --bean idmapperScannerConfigurer classorg.mybatis.spring.mapper.MapperScannerConfigurer!-- 待扫描的mapper 接口的包名 多个之间使用逗号分隔 --property namebasePackage valuecom.bjpowernode.mapper /!--注入SqlSessionFactoryBean 用于创建SqlSession --property namesqlSessionFactoryBeanName valuesqlSessionFactoryBean //bean!-- 配置Service 层对象 --bean iduserService classcom.bjpowernode.service.impl.UserServiceImpl autowirebyType //beans5.2 Spring配置文件版 使用Spring的配置文件取代mybatis的核心配置文件。 导入的jar包和相关类完全一致jdbc配置文件和日志配置文件也相同。只是将mybatis的核心配置文件中的配置移入到spring的核心配置文件中。 5.2.1 Spring核心配置文件 ?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/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd!--终极目标 为 每个service 注入一个Mapper 对象1. Mapper 对象2. SqlSession 获取3. SqlSession 要根据 SqlSessionFactory 获取4. SqlSessionFactory 要 根据 SqlSessionFactoryBuilder获取5. SqlSessionFactoryBuilder 可以直接创建 此时需要使用IOC容器6. 配置数据源--!--1. 引入jdbc的配置文件 使用配置文件 不是使用系统属性--context:property-placeholder locationjdbc.properties system-properties-modeFALLBACK /!--2. 配置数据源 --bean iddataSource classorg.springframework.jdbc.datasource.DriverManagerDataSourceproperty namedriverClassName value${jdbc.driver}/propertyproperty nameurl value${jdbc.url}/propertyproperty nameusername value${jdbc.username}/propertyproperty namepassword value${jdbc.password}/property/bean!--3. 配置SqlSessionFactoryBean 对象--bean idsqlSessionFactoryBean classorg.mybatis.spring.SqlSessionFactoryBean!-- 配置数据源 --property namedataSource refdataSource /!-- 配置包下类别名 多个包之间使用 逗号分隔 --property nametypeAliasesPackage valuecom.bjpowernode.domain /!-- 配置插件 --property namepluginsarraybean idpageInterceptor classcom.github.pagehelper.PageInterceptor //array/property!-- 配置映射文件 --property namemapperLocations valuemapper/**/*Mapper.xml/property/bean!-- 4.扫描所有的Mapper接口 自动创建Mapper的代理对象 --bean idmapperScannerConfigurer classorg.mybatis.spring.mapper.MapperScannerConfigurer!-- 待扫描的mapper 接口的包名 多个之间使用逗号分隔 --property namebasePackage valuecom.bjpowernode.mapper /!--注入SqlSessionFactoryBean 用于创建SqlSession --!--SqlSessionFactoryBean 是可以自动装配的 但是 如果存在多个数据源时可以指定SqlSessionFactoryBean区分数据源--property namesqlSessionFactoryBeanName valuesqlSessionFactoryBean //bean!-- 配置Service 层对象 --bean iduserService classcom.bjpowernode.service.impl.UserServiceImpl autowirebyType //beans 5.2.2 配置日志 ?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/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd!--终极目标 为 每个service 注入一个Mapper 对象1. Mapper 对象2. SqlSession 获取3. SqlSession 要根据 SqlSessionFactory 获取4. SqlSessionFactory 要 根据 SqlSessionFactoryBuilder获取5. SqlSessionFactoryBuilder 可以直接创建 此时需要使用IOC容器6. 配置数据源--!--1. 引入jdbc的配置文件 使用配置文件 不是使用系统属性--context:property-placeholder locationjdbc.properties system-properties-modeFALLBACK /!--2. 配置数据源 --bean iddataSource classorg.springframework.jdbc.datasource.DriverManagerDataSourceproperty namedriverClassName value${jdbc.driver}/propertyproperty nameurl value${jdbc.url}/propertyproperty nameusername value${jdbc.username}/propertyproperty namepassword value${jdbc.password}/property/bean!-- 配置 Configuration--bean idconfiguration classorg.apache.ibatis.session.Configuration!-- 指定日志工具 --property namelogImpl valueorg.apache.ibatis.logging.log4j.Log4jImpl /!-- 配置缓存 --property namecacheEnabled valuetrue //bean!--3. 配置SqlSessionFactoryBean 对象--bean idsqlSessionFactoryBean classorg.mybatis.spring.SqlSessionFactoryBean!-- 配置数据源 --property namedataSource refdataSource /!-- 配置包下类别名 多个包之间使用 逗号分隔 --property nametypeAliasesPackage valuecom.bjpowernode.domain /!-- 配置插件 --property namepluginsarraybean idpageInterceptor classcom.github.pagehelper.PageInterceptor //array/property!-- 注入configuration --property nameconfiguration refconfiguration /!-- 配置映射文件 --property namemapperLocations valuemapper/**/*Mapper.xml/property/bean!-- 4.扫描所有的Mapper接口 自动创建Mapper的代理对象 --bean idmapperScannerConfigurer classorg.mybatis.spring.mapper.MapperScannerConfigurer!-- 待扫描的mapper 接口的包名 多个之间使用逗号分隔 --property namebasePackage valuecom.bjpowernode.mapper /!--注入SqlSessionFactoryBean 用于创建SqlSession --!--SqlSessionFactoryBean 是可以自动装配的 但是 如果存在多个数据源时可以指定SqlSessionFactoryBean区分数据源--property namesqlSessionFactoryBeanName valuesqlSessionFactoryBean //bean!-- 配置Service 层对象 --bean iduserService classcom.bjpowernode.service.impl.UserServiceImpl autowirebyType //beans 6.声明式事务 在spring中spring可以管理数据源管理连接,spring也可以管理事务,并且spring单独对事务分了一个模块进行管理。并且Spring简化了事务开发只需要通过配置的方式Spring即可对事务进行统一完善的管理Spring的事务管理基于Spring的AOP技术。 Spring的声明式事务有两种方式xml配置、注解 6.1 XML配置方式 ?xml version1.0 encodingUTF-8? beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexmlns:contexthttp://www.springframework.org/schema/context xmlns:txhttp://www.springframework.org/schema/txxmlns:aophttp://www.springframework.org/schema/aopxsi:schemaLocationhttp://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd!--终极目标 为 每个service 注入一个Mapper 对象1. Mapper 对象2. SqlSession 获取3. SqlSession 要根据 SqlSessionFactory 获取4. SqlSessionFactory 要 根据 SqlSessionFactoryBuilder获取5. SqlSessionFactoryBuilder 可以直接创建 此时需要使用IOC容器6. 配置数据源--!--1. 引入jdbc的配置文件 使用配置文件 不是使用系统属性--context:property-placeholder locationjdbc.properties system-properties-modeFALLBACK /!--2. 配置数据源 --bean iddataSource classorg.springframework.jdbc.datasource.DriverManagerDataSourceproperty namedriverClassName value${jdbc.driver}/propertyproperty nameurl value${jdbc.url}/propertyproperty nameusername value${jdbc.username}/propertyproperty namepassword value${jdbc.password}/property/bean!-- 配置 Configuration--bean idconfiguration classorg.apache.ibatis.session.Configuration!-- 指定日志工具 --property namelogImpl valueorg.apache.ibatis.logging.log4j.Log4jImpl /!-- 配置缓存 --property namecacheEnabled valuetrue //bean!--3. 配置SqlSessionFactoryBean 对象--bean idsqlSessionFactoryBean classorg.mybatis.spring.SqlSessionFactoryBean!-- 配置数据源 --property namedataSource refdataSource /!-- 配置包下类别名 多个包之间使用 逗号分隔 --property nametypeAliasesPackage valuecom.bjpowernode.domain /!-- 配置插件 --property namepluginsarraybean idpageInterceptor classcom.github.pagehelper.PageInterceptor //array/property!-- 注入configuration --property nameconfiguration refconfiguration /!-- 配置映射文件 --property namemapperLocations valuemapper/**/*Mapper.xml/property/bean!-- 4.扫描所有的Mapper接口 自动创建Mapper的代理对象 --bean idmapperScannerConfigurer classorg.mybatis.spring.mapper.MapperScannerConfigurer!-- 待扫描的mapper 接口的包名 多个之间使用逗号分隔 --property namebasePackage valuecom.bjpowernode.mapper /!--注入SqlSessionFactoryBean 用于创建SqlSession --!--SqlSessionFactoryBean 是可以自动装配的 但是 如果存在多个数据源时可以指定SqlSessionFactoryBean区分数据源--property namesqlSessionFactoryBeanName valuesqlSessionFactoryBean //bean!-- 配置Service 层对象 --bean iduserService classcom.bjpowernode.service.impl.UserServiceImpl autowirebyType /!-- 事务管理器 --bean idtransactionManager classorg.springframework.jdbc.datasource.DataSourceTransactionManager!-- 配置数据源 指定要管理那个数据源的事务 --property namedataSource refdataSource //bean!-- 配置事务增强 --tx:advice idtxAdvice transaction-managertransactionManager!-- 配置增强规则 --tx:attributes!--name : 进行数据库操作方法的名称 add* 表示 add开头的方法 * 指代任意字符propagation : 事务传播性 面试重点read-only : 只读事务 默认 falserollback-for : 指定回滚的异常 默认是 RunTimeException 下的异常会自动回滚no-rollback-for : 不回滚的异常timeout : 事务的超时时间isolation : 事务隔离级别 面试重点| 1. 读未提交| 2. 读已提交| 3. 可重复读| 4. 串行化--tx:method nameadd* read-only”false” rollback-forException/tx:method nameinsert* rollback-forException /tx:method nameupdate* rollback-forException /tx:method namedelete* rollback-forException /tx:method name* read-onlytrue //tx:attributes/tx:advice!-- 配置切面 --aop:config!-- 注意一般切点在 service --aop:pointcut idmypoint expressionexecution(* com.bjpowernode.service.impl.*.*(..))/!-- 织入增强 --aop:advisor advice-reftxAdvice pointcut-refmypoint //aop:config /beans6.2 注解版声明式事务 在Spring中为简化事务开发提供了注解Transactional该注解可以指定在类上在类上该类中的所有方法都会使用事务该注解也可以指定方法上该方法会使用事务。使用非常简单只需 配置事务管理器 开启注解事务 在需要使用事务的地方使用Transactional 6.2.1 配置类 ?xml version1.0 encodingUTF-8? beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexmlns:contexthttp://www.springframework.org/schema/context xmlns:txhttp://www.springframework.org/schema/txxmlns:aophttp://www.springframework.org/schema/aopxsi:schemaLocationhttp://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd!--终极目标 为 每个service 注入一个Mapper 对象1. Mapper 对象2. SqlSession 获取3. SqlSession 要根据 SqlSessionFactory 获取4. SqlSessionFactory 要 根据 SqlSessionFactoryBuilder获取5. SqlSessionFactoryBuilder 可以直接创建 此时需要使用IOC容器6. 配置数据源--!--1. 引入jdbc的配置文件 使用配置文件 不是使用系统属性--context:property-placeholder locationjdbc.properties system-properties-modeFALLBACK /!--2. 配置数据源 --bean iddataSource classorg.springframework.jdbc.datasource.DriverManagerDataSourceproperty namedriverClassName value${jdbc.driver}/propertyproperty nameurl value${jdbc.url}/propertyproperty nameusername value${jdbc.username}/propertyproperty namepassword value${jdbc.password}/property/bean!-- 配置 Configuration--bean idconfiguration classorg.apache.ibatis.session.Configuration!-- 指定日志工具 --property namelogImpl valueorg.apache.ibatis.logging.log4j.Log4jImpl /!-- 配置缓存 --property namecacheEnabled valuetrue //bean!--3. 配置SqlSessionFactoryBean 对象--bean idsqlSessionFactoryBean classorg.mybatis.spring.SqlSessionFactoryBean!-- 配置数据源 --property namedataSource refdataSource /!-- 配置包下类别名 多个包之间使用 逗号分隔 --property nametypeAliasesPackage valuecom.bjpowernode.domain /!-- 配置插件 --property namepluginsarraybean idpageInterceptor classcom.github.pagehelper.PageInterceptor //array/property!-- 注入configuration --property nameconfiguration refconfiguration /!-- 配置映射文件 --property namemapperLocations valuemapper/**/*Mapper.xml/property/bean!-- 4.扫描所有的Mapper接口 自动创建Mapper的代理对象 --bean idmapperScannerConfigurer classorg.mybatis.spring.mapper.MapperScannerConfigurer!-- 待扫描的mapper 接口的包名 多个之间使用逗号分隔 --property namebasePackage valuecom.bjpowernode.mapper /!--注入SqlSessionFactoryBean 用于创建SqlSession --!--SqlSessionFactoryBean 是可以自动装配的 但是 如果存在多个数据源时可以指定SqlSessionFactoryBean区分数据源--property namesqlSessionFactoryBeanName valuesqlSessionFactoryBean //bean!-- 事务管理器 --bean idtransactionManager classorg.springframework.jdbc.datasource.DataSourceTransactionManager!-- 配置数据源 指定要管理那个数据源的事务 --property namedataSource refdataSource //bean!-- 开启组件扫描 --context:component-scan base-packagecom.* /!-- 开启事务注解 --tx:annotation-driven transaction-managertransactionManager / /beans 6.2.2 service代码 package com.bjpowernode.service.impl;import com.github.pagehelper.Page; import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; import com.bjpowernode.domain.User; import com.bjpowernode.mapper.UserMapper; import com.bjpowernode.service.IUserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional;Service Transactional(rollbackFor Exception.class) public class UserServiceImpl implements IUserService {Autowiredprivate UserMapper userMapper;Overridepublic User queryUser(Integer id) {return userMapper.selectById(id);}Overridepublic PageInfoUser queryPage(Integer page,Integer limit) {PageUser users PageHelper.startPage(page, limit);userMapper.selectAll();return users.toPageInfo();}/*** 在spring中 不要在事务相关方法中 使用catch 处理* 如果处理了 异常不会被spring aop 增强的方法 捕获到 不会回滚* 事务配置就失效了 所以如果有异常 * 1. 直接抛* 2. 在catch继续抛出异常* param user* return*/Override//Transactional(rollbackFor Exception.class)public Integer addUser(User user) {int m userMapper.insert(user);int n 0;try {m m/n;//出现异常} catch (Exception exception) {exception.printStackTrace();throw new RuntimeException(发生 请求回滚!!!);}return m;} }7 注意 事务的传播行为是指事务会发生传递。例如A方法存在事务A调用B方法那么B方法也会在事务中执行这种就是事务的传播行为。 package com.bjpowernode.controller;import com.bjpowernode.domain.User; import com.bjpowernode.mapper.UserMapper; import com.bjpowernode.service.IUserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.transaction.annotation.Transactional;Controller public class UserController {Autowiredprivate IUserService userService;Autowiredprivate UserMapper userMapper;Transactionalpublic void add(User user){User user1 new User();user1.setUsername(韩梅梅);user1.setPassword(123);user1.setRealname(韩梅梅);userMapper.insert(user1);//在父事务中添加数据 自己的程序 更新数据状态try {//其他的业务操作userService.addUser(user);//子事务 子事务发生异常}catch (Exception e){e.printStackTrace();}int n 0;//n 100/n;//出现异常} }package com.bjpowernode.service.impl;import com.github.pagehelper.Page; import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; import com.bjpowernode.domain.User; import com.bjpowernode.mapper.UserMapper; import com.bjpowernode.service.IUserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional;Service public class UserServiceImpl implements IUserService {Autowiredprivate UserMapper userMapper;Overridepublic User queryUser(Integer id) {return userMapper.selectById(id);}Overridepublic PageInfoUser queryPage(Integer page,Integer limit) {PageUser users PageHelper.startPage(page, limit);userMapper.selectAll();return users.toPageInfo();}/*** 在spring中 不要在事务相关方法中 使用catch 处理* 如果处理了 异常不会被spring aop 增强的方法 捕获到 不会回滚* 事务配置就失效了 所以如果有异常 * 1. 直接抛* 2. 在catch继续抛出异常* param user* return*/Override//Transactional(propagation Propagation.SUPPORTS) //有就在事务中执行 没有就不在事务中执行//Transactional(propagation Propagation.MANDATORY) //必须要有事务//Transactional(propagation Propagation.NEVER) // 不在事务中执行 当前存在事务就报错Transactional(propagation Propagation.NESTED) // 当前存在一个事务 就 创建一个子事务 嵌套在当前事务中//外层事务出现异常会回滚子事务 子事务出现异常 不会回滚外层事务public Integer addUser(User user) {int m userMapper.insert(user);int n 0;m m/n;//出现异常return m;} }
http://www.tj-hxxt.cn/news/225012.html

相关文章:

  • 找做仿网站怎么补网站漏洞
  • 用php做的网站必备那些文件专业网站建设是哪家便宜
  • 开源cms建站WordPress文章过滤
  • 建个站的网站打不开辛集做网站公司
  • 哪些购物网站做的比较简洁有品质wordpress弹窗
  • 湘潭市 网站建设如何做双语网站
  • 网站营销单页怎么设计方案招投标网站开发费用
  • 诚讯通网站网站的建设
  • 西安营销网站建设公司做网站彩票代理多少钱啊
  • 手机网站怎么做域名解析广州英文建站公司
  • 扁平化手机网站模板陕西省平安建设网站
  • 专业的网站开发公司电话上海做网站天锐
  • 装潢公司网站源码php封面设计用什么软件做
  • 网站建设 案例展示网站原型怎么做
  • 网站建设预计资金投入天美传媒传媒官网免费下载
  • 廊坊网站搜索优化百度搜索引擎怎么做
  • 广州网站建设菲利宾手机百度下载安装
  • 长春做高端网站公司营销推广内容
  • 那个网站做图片比较赚钱售后好的品牌策划公司
  • 黑龙江省住房和建设厅网站首页洛阳理工学院教务管理系统
  • 个人无网站怎样做cps广告电子报刊的传播媒体是什么
  • 什么网站好建设wordpress支付宝当面付插件
  • 昆明网站建设哪家好iis 配置 wordpress
  • 怎么才能让百度收录网站wordpress文章推送公众号
  • 花网站开发背景物业管理系统和物业管理软件
  • 沧州哪家做网站好wordpress 支持rar
  • 企业管理咨询公司注册条件河北百度seo点击软件
  • 山东专业企业网站建设做企业网站报价
  • 网站外链接自己可以怎么做wordpress建站不好用
  • 郑州网站维护电商网站开发ppt