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

网站制作教程步骤常州企业网站建站模板

网站制作教程步骤,常州企业网站建站模板,移动论坛网站模板免费下载,现在怎么做网络推广Spring简介 Spring是一个开源框架#xff0c;为简化企业级开发而生。它以IOC#xff08;控制反转#xff09;和AOP#xff08;面向切面#xff09;为思想内核#xff0c;提供了控制层 SpringMVC、数据层SpringData、服务层事务管理等众多技术#xff0c;并可以整合众多…Spring简介 Spring是一个开源框架为简化企业级开发而生。它以IOC控制反转和AOP面向切面为思想内核提供了控制层 SpringMVC、数据层SpringData、服务层事务管理等众多技术并可以整合众多第三方框架。 Spring将很多复杂的代码变得优雅简洁有效的降低代码的耦合度极大的方便项目的后期维护、升级和扩展。 Spring官网地址https://spring.io/ Spring体系结构 Spring框架根据不同的功能被划分成了多个模块这些模块可以满足一切企业级应用开发的需求在开发过程中可以根据需求有选择性地使用所需要的模块。 Core ContainerSpring核心模块任何功能的使用都离不开该模块是其他模块建立的基础。Data Access/Integration该模块提供了数据持久化的相应功能。Web该模块提供了web开发的相应功能。AOP提供了面向切面编程实现Aspects提供与AspectJ框架的集成该框架是一个面向切面编程框架。Instrumentation提供了类工具的支持和类加载器的实现可以在特定的应用服务器中使用。Messaging为Spring框架集成一些基础的报文传送应用Test提供与测试框架的集成 IOC_控制反转思想 IOC(Inversion of Control) 程序将创建对象的权利交给框架。 之前在开发过程中对象实例的创建是由调用者管理的 这种写法有两个缺点 浪费资源StudentService调用方法时即会创建一个对象如果不断调用方法则会创建大量StudentDao对象。代码耦合度高假设随着开发我们创建了StudentDao另一个更加完善的实现类StudentDaoImpl2如果在StudentService中想使用StudentDaoImpl2则必须修改源码。 而IOC思想是将创建对象的权利交给框架框架会帮助我们创建对象分配对象的使用控制权由程序代码转移到了框架中控制权 发生了反转这就是Spring的IOC思想。而IOC思想可以完美的解决以上两个问题。 IOC_Spring实现IOC 创建Maven工程引入依赖 dependenciesdependencygroupIdorg.springframework/groupIdartifactIdspring-context/artifactIdversion5.3.13/version/dependencydependencygroupIdjunit/groupIdartifactIdjunit/artifactIdversion4.12/versionscopetest/scope/dependency /dependencies创建POJO类、Dao类和接口 public class Student {private int id;private String name;private String address;// 省略getter/setter/构造方法/tostring } public interface StudentDao {// 根据id查询学生Student findById(int id); } public class StudentDaoImpl implements StudentDao{Overridepublic Student findById(int id) {// 模拟从数据库查找出学生return new Student(1,程序员,北京);} }编写xml配置文件配置文件中配置需要Spring帮我们创建的对象 ?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.xsdbean idstudentDao classcom.gb.dao.StudentDaoImpl/bean /beans测试从Spring容器中获取对象。 public class TestContainer {Testpublic void t1(){// 创建Spring容器ApplicationContext ac new ClassPathXmlApplicationContext(bean.xml);// 从容器获取对象StudentDao studentDao1 (StudentDao) ac.getBean(studentDao);StudentDao studentDao2 (StudentDao) ac.getBean(studentDao);System.out.println(studentDao1.hashCode());System.out.println(studentDao2.hashCode());System.out.println(studentDao1.findById(1));} }IOC_Spring容器类型 容器接口 BeanFactoryBeanFactory是Spring容器中的顶层接口它可以对Bean对象进行管理。ApplicationContextApplicationContext是BeanFactory的子接口。它除了继承 BeanFactory的所有功能外还添加了对国际化、资源访问、事件传播等方面的良好支持。 ApplicationContext有以下三个常用实现类 ClassPathXmlApplicationContext该类可以从项目中读取配置文件FileSystemXmlApplicationContext该类从磁盘中读取配置文件AnnotationConfigApplicationContext使用该类不读取配置文件而是会读取注解 Test public void t2(){// 创建spring容器// ApplicationContext ac new ClassPathXmlApplicationContext(bean.xml); ApplicationContext ac new FileSystemXmlApplicationContext(C:\\Users\\a\\IdeaProjects\\spring_demo\\src\\main\\resources\\bean.xml);// 从容器中获取对象StudentDao userDao (StudentDao)ac.getBean(studentDao);System.out.println(userDao);System.out.println(userDao.findById(1)); }IOC_对象的创建方式 使用构造方法 Spring默认使用类的空参构造方法创建bean 使用工厂类的方法 Spring可以调用工厂类的方法创建bean 创建工厂类工厂类提供创建对象的方法 public class StudentDaoFactory {public StudentDao getStudentDao(){return new StudentDaoImpl(1);} }在配置文件中配置创建bean的方式为工厂方式。 bean idstudentDaoFactory classcom.gb.dao.StudentDaoFactory/bean !-- idbean对象的idfactory-bean工厂对象的idfactory-method工厂方法 -- bean idstudentDao factory-beanstudentDaoFactory factory-methodgetStudentDao/bean使用工厂类的静态方法 Spring可以调用工厂类的静态方法创建bean !-- id:bean的id class:工厂全类名 factory-method:工厂静态方法 -- bean idstudentDao classcom.gb.dao.StudentDaoFactory2 factory-methodgetStudentDao/beanIOC_对象的创建策略 Spring通过配置 bean 中的 scope 属性设置对象的创建策略共有五种创建策略 singleton单例默认策略。整个项目只会创建一个对象通过 bean 中的 lazy-init 属性可以设置单例对象的创建时机 lazy-init“false”(默认)立即创建在容器启动时会创建配置文件中的所有Bean对象。 lazy-init“true”延迟创建第一次使用Bean对象时才会创建。 prototype多例每次从容器中获取时都会创建对象。request每次请求创建一个对象只在web环境有效。session每次会话创建一个对象只在web环境有效。gloabal-session一次集群环境的会话创建一个对象只在web环境有效。 IOC_对象的销毁时机 对象的创建策略不同销毁时机也不同 singleton对象随着容器的销毁而销毁。prototype使用JAVA垃圾回收机制销毁对象。request当处理请求结束bean实例将被销毁。session当HTTP Session最终被废弃的时候bean也会被销毁掉。gloabal-session集群环境下的session销毁bean实例也将被销毁。 IOC_生命周期方法 Bean对象的生命周期包含创建——使用——销毁Spring可以配置Bean对象在创建和销毁时自动执行的方法 定义生命周期方法 public class StudentDaoImpl2 implements StudentDao{// 创建时自动执行的方法public void init(){System.out.println(创建StudentDao);}// 销毁时自动执行的方法public void destory(){System.out.println(销毁StudentDao);} }配置生命周期方法 !-- init-method:创建对象时执行的方法 destroy-method:销毁对象时执行的方法 -- bean idstudentDao classcom.gb.dao.StudentDaoImpl2 scopesingleton init-methodinit destroy-methoddestory/bean测试 Test public void t3(){// 创建Spring容器ClassPathXmlApplicationContext ac new ClassPathXmlApplicationContext(bean1.xml);// 销毁Spring容器ClassPathXmlApplicationContext才有销毁容器的方法ac.close(); }IOC_获取Bean对象的方式 通过id/name获取 配置文件 bean namestudentDao classcom.gb.dao.StudentDaoImpl2/bean bean idstudentDao classcom.gb.dao.StudentDaoImpl2/bean获取对象 StudentDao studentDao (StudentDao)ac.getBean(studentDao);通过类型获取 配置文件 bean namestudentDao classcom.gb.dao.StudentDaoImpl2/bean获取对象 StudentDao studentDao (StudentDao)ac.getBean(StudentDao.class);可以看到使用类型获取不需要强转。 通过类型id/name获取 虽然使用类型获取不需要强转但如果在容器中有一个接口的多个实现类对象则获取时会报错此时需要使用类型id/name获取 配置文件 bean namestudentDao classcom.gb.dao.StudentDaoImpl2/bean bean namestudentDao1 classcom.gb.dao.StudentDaoImpl/bean获取对象 StudentDao studentDao2 ac.getBean(studentDao,StudentDao.class);DI_什么是依赖注入 依赖注入Dependency Injection简称DI它是Spring控制反转思想的具体实现。 控制反转将对象的创建交给了Spring但是对象中可能会依赖其他对象。比如service类中要有dao类的属性我们称service依赖于dao。 简单来说控制反转是创建对象依赖注入是为对象的属性赋值。 DI_依赖注入方式 Setter注入 1 被注入类编写属性的setter方法 public class StudentService {private StudentDao studentDao;public void setStudentDao(StudentDao studentDao) {this.studentDao studentDao;} }配置文件中给需要注入属性值的 bean 中设置 property bean idstudentDao classcom.gb.dao.StudentDaoImpl/bean bean idstudentService classcom.gb.service.StudentService!--依赖注入--!--name:对象的属性名 ref:容器中对象的id值--property namestudentDao refstudentDao/property /bean构造方法注入 被注入类编写有参的构造方法 public class StudentService {private StudentDao studentDao;public StudentService(StudentDao studentDao) {this.studentDao studentDao;} }给需要注入属性值的 bean 中设置 constructor-arg bean idstudentDao classcom.gb.dao.StudentDaoImpl/bean bean idstudentService classcom.gb.service.StudentService!-- 依赖注入 --!-- name:对象的属性名 ref配置文件中注入对象的id值 --constructor-arg namestudentDao refstudentDao/constructor-arg /bean自动注入 自动注入不需要在 bean 标签中添加其他标签注入属性值而是自动从容器中找到相应的bean对象设置为属性值。 自动注入有两种配置方式 全局配置在 beans 中设置 default-autowire 属性可以定义所有bean对象的自动注入策略。局部配置在 bean 中设置 autowire 属性可以定义当前bean对象的自动注入策略。 autowire的取值如下 no不会进行自动注入。default全局配置default相当于no局部配置default表示使用全局配置byName在Spring容器中查找id与属性名相同的bean并进行注入。需要提供set方法。byType在Spring容器中查找类型与属性类型相同的bean并进行注入。需要提供set方法。constructor在Spring容器中查找id与属性名相同的bean并进行注入。需要提供构造方法。 测试自动注入 为依赖的对象提供setter和构造方法 public class StudentService {// 依赖private StudentDao studentDao;// 构造方法public StudentService() {}public StudentService(StudentDao studentDao) {this.studentDao studentDao;}// setter方法public void setStudentDao(StudentDao studentDao) {this.studentDao studentDao;}// 调用依赖的方法public Student findStudentById(int id){return studentDao.findById(id);} }配置自动注入 !-- 根据beanId等于属性名自动注入 -- bean idstudentDao classcom.gb.dao.StudentDaoImpl/bean bean idstudentServiceclasscom.gb.service.StudentService autowirebyName/bean!-- 根据bean类型等于属性类型自动注入 -- bean idstudentDao classcom.gb.dao.StudentDaoImpl/bean bean idstudentService classcom.gb.service.StudentService autowirebyType/bean!-- 利用构造方法自动注入 -- bean idstudentDao classcom.gb.dao.StudentDaoImpl/bean bean idstudentService classcom.gb.service.StudentService autowireconstructor/bean!-- 配置全局自动注入 -- 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.xsddefault-autowireconstructorDI_依赖注入类型 DI支持注入bean类型、基本数据类型和字符串、List集合、Set集合、Map集合、Properties对象类型等他们的写法如下 准备注入属性的类 public class StudentService {private StudentDao studentDao; // bean属性private String name; //字符串类型private int count; //基本数据类型private ListString names; // 字符串类型List集合private ListStudent students1; // 对象类型List集合private SetStudent students2; // 对象类型Set集合private MapString,String names2; //字符串类型Map集合private MapString,Student students3;// 对象类型Map集合private Properties properties;//Properties类型// 省略getter/setter/toString }注入bean类型 写法一 bean idstudentDao classcom.gb.dao.StudentDaoImpl/bean bean idstudentService classcom.gb.service.StudentServiceproperty namestudentDao refstudentDao/property /bean写法二 bean idstudentDao classcom.itbaizhan.dao.StudentDaoImpl/bean bean idstudentService classcom.itbaizhan.service.StudentServiceproperty namestudentDao ref beanstudentDao/ref/property /bean注入基本数据类型 bean idstudentService classcom.itbaizhan.service.StudentService!-- 写法一 name属性名 value属性值--property namename value程序员/property!-- 写法二 name属性名 value属性值--property namecountvalue10/value/property /bean注入List集合 bean idstudentService classcom.gb.service.StudentService!-- 简单数据类型List集合 name属性名 --property namenameslistvalue程序员/valuevalue悍匪/value/list/property!-- 对象类型List集合 name属性名 --property namestudents1listbean classcom.gb.domain.Studentproperty nameid value1/property namename valueJava/property nameaddress value北京//beanbean classcom.gb.domain.Studentproperty nameid value2/property namename value大数据/property nameaddress value北京//bean/list/property /bean注入Set集合 bean idstudentService classcom.itbaizhan.service.StudentService!-- Set集合 --property namestudents2setbean classcom.itbaizhan.domain.Studentproperty nameid value1/property namename value悍匪/property nameaddress value北京//beanbean classcom.itbaizhan.domain.Studentproperty nameid value2/property namename value程序员/property nameaddressvalue北京//bean/set/property /bean注入Map集合 简单数据类型Map集合 bean idstudentService classcom.gb.service.StudentServiceproperty namenames2mapentry keystudent1 valuebz/entry keystudent2 valuesxt//map/property /bean对象类型Map集合 bean idstudentService classcom.gb.service.StudentServiceproperty namestudents3mapentry keystudent1 value-refs1/entry keystudent2 valuerefs2//map/property /bean bean ids1classcom.gb.domain.Studentproperty nameid value1/property namename value尚学堂/property nameaddress value北京/ /bean bean ids2 classcom.gb.domain.Studentproperty nameid value2/property namename value百战/property nameaddress value北京/ /bean 注入Properties对象 bean idstudentService classcom.gb.service.StudentServiceproperty namepropertiespropsprop key配置1值1/propprop key配置2值2/prop/props/property /bean注解实现IOC 准备工作 创建一个新的Spring项目。编写pojodaoservice类。编写空的配置文件如果想让该文件支持注解需要添加新的约束 ?xml version1.0 encodingUTF-8? beans xmlnshttp://www.springframework.org/schema/beansxmlns:contexthttp://www.springframework.org/schema/contextxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi: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 /beansComponent注解 作用用于创建对象放入Spring容器相当于 bean id class 位置类上方 注意 要在配置文件中配置扫描的包扫描到该注解才能生效。 !-- 扫描包 --context:component-scan base-packagecom.gb/context:component-scanComponent 注解配置bean的默认id是首字母小写的类名。也可以手动设置bean的id值。 // 此时bean的id为studentDaoImpl Component public class StudentDaoImpl implements StudentDao{public Student findById(int id) {// 模拟根据id查询学生return new Student(1,程序员,北京);} }// 此时bean的id为studentDao Component(studentDao) public class StudentDaoImpl implements StudentDao{public Student findById(int id) {// 模拟根据id查询学生return new Student(1,程序员,北京);} }Repository、Service、Controller 作用这三个注解和Component的作用一样使用它们是为了区分该类属于什么层。 位置 Repository用于Dao层Service用于Service层Controller用于Controller层 Scope 作用指定bean的创建策略 位置类上方 取值singleton prototype request session globalsession Service Scope(singleton) public class StudentService {}Autowired 作用从容器中查找符合属性类型的对象自动注入属性中。用于代替 bean 中的依赖注入配置。 位置属性上方、setter方法上方、构造方法上方。 注意 Autowired 写在属性上方进行依赖注入时可以省略setter方法。容器中没有对应类型的对象会报错容器中有多个对象匹配类型时会找beanId等于属性名的对象找不到会报错。 Qualifier 作用在按照类型注入对象的基础上再按照bean的id注入。 位置属性上方 注意Qualifier必须和Autowired一起使用。 Value 作用注入String类型和基本数据类型的属性值。 位置属性上方 Configuration 纯注解实现IOC需要一个Java类代替xml文件。这个Java类上方需要添加Configuration表示该类是一个配置类作用是代替配置文件。 Configuration public class SpringConfig { }ComponentScan 作用指定spring在初始化容器时扫描的包。 位置配置类上方 Configuration ComponentScan(com.gb) public class SpringConfig { }PropertySource 作用代替配置文件中的 context:property-placeholder 扫描配置文件 位置配置类上方 注意配置文件位置前要加关键字 classpath Configuration PropertySource(classpath:db.properties) public class JdbcConfig {Value(${jdbc.username})private String username;Value(${jdbc.password})private String password; }Bean 作用将方法的返回值对象放入Spring容器中。如果想将第三方类的对象放入容器可以使用Bean 位置配置类的方法上方。 属性name给bean对象设置id 注意Bean修饰的方法如果有参数spring会根据参数类型从容器中查找可用对象。 Import 作用如果配置过多会有多个配置类该注解可以为主配置类导入其他配置类 位置主配置类上方 SpringAOP_AOP简介 AOP的全称是Aspect Oriented Programming即面向切面编程。是实现功能统一维护的一种技术它将业务逻辑的各个部分进行隔 离使开发人员在编写业务逻辑时可以专心于核心业务从而提高了开发效率。 作用在不修改源码的基础上对已有方法进行增强。实现原理动态代理技术。优势减少重复代码、提高开发效率、维护方便应用场景事务处理、日志管理、权限控制、异常处理等方面。 SpringAOP_AOP相关术语 名称说明Joinpoint连接点 指能被拦截到的点在Spring中只有方法能被拦截。Pointcut切点 指要对哪些连接点进行拦截即被增强的方法。Advice通知 指拦截后要做的事情即切点被拦截后执行的方法。Aspect切面 切点通知称为切面Target目标 被代理的对象Proxy代理 代理对象Weaving织入 生成代理对象的过程 SpringAOP_AOP入门 AspectJ是一个基于Java语言的AOP框架在Spring框架中建议使用AspectJ实现AOP。 接下来我们写一个AOP入门案例dao层的每个方法结束后都可以打印一条日志 引入依赖 !-- spring -- dependencygroupIdorg.springframework/groupIdartifactIdspringcontext/artifactIdversion5.3.13/version /dependency !-- AspectJ -- dependencygroupIdorg.aspectj/groupIdartifactIdaspectjweaver/artifactIdversion1.8.7/version /dependency !-- junit -- dependencygroupIdjunit/groupIdartifactIdjunit/artifactIdversion4.12/versionscopetest/scope /dependency编写连接点 Repository public class UserDao {public void add(){System.out.println(用户新增);}public void delete(){System.out.println(用户删除);}public void update(){System.out.println(用户修改);} }编写通知类 public class MyAspectJAdvice {// 后置通知public void myAfterReturning() {System.out.println(打印日志...);} }配置切面 ?xml version1.0 encodingUTF-8? beans xmlnshttp://www.springframework.org/schema/beansxmlns:contexthttp://www.springframework.org/schema/contextxmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xmlns:txhttp://www.springframework.org/schema/txxmlns:aophttp://www.springframework.org/schema/aopxsi: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 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.xsdcontext:component-scan base-packagecom.gb/context:component-scan!-- 通知对象 --bean idmyAspectJAdvice classcom.gb.advice.MyAspectAdvice/bean!-- 配置AOP --aop:config!-- 配置切面 --aop:aspect refmyAspectJAdvice!-- 配置切点 --aop:pointcut idmyPointcut expressionexecution(* com.gb.dao.UserDao.*(..))/!-- 配置通知 --aop:after-returning methodmyAfterReturning pointcut-refmyPointcut//aop:aspect/aop:config /beansSpringAOP_通知类型 AOP有以下几种常用的通知类型 通知类型描述前置通知在方法执行前添加功能后置通知在方法正常执行后添加功能异常通知在方法抛出异常后添加功能最终通知无论方法是否抛出异常都会执行该通知环绕通知在方法执行前后添加功能 编写通知方法 // 通知类 public class MyAspectAdvice {// 后置通知public void myAfterReturning(JoinPoint joinPoint) {System.out.println(切点方法名 joinPoint.getSignature().getName());System.out.println(目标对象 joinPoint.getTarget());System.out.println(打印日志 joinPoint.getSignature().getName() 方法被执行了);}// 前置通知public void myBefore() {System.out.println(前置通知...);}// 异常通知public void myAfterThrowing(Exception ex) {System.out.println(异常通知...);System.err.println(ex.getMessage());}// 最终通知public void myAfter() {System.out.println(最终通知);}// 环绕通知public Object myAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {System.out.println(环绕前);Object obj proceedingJoinPoint.proceed(); // 执行方法System.out.println(环绕后);return obj;} }配置切面 !-- 配置AOP -- aop:config!-- 配置切面 --aop:aspect refmyAspectJAdvice!-- 配置切点 -- aop:pointcut idmyPointcut expressionexecution(* com.gb.dao.UserDao.*(..))/!-- 前置通知 --aop:before methodmyBefore pointcut-refmyPointcut/aop:before!-- 后置通知 --aop:after-returning methodmyAfterReturning pointcutrefmyPointcut/!-- 异常通知 --aop:after-throwing methodmyAfterThrowing pointcutrefmyPointcut throwingex/!-- 最终通知 --aop:after methodmyAfter pointcut-refmyPointcut/aop:after!-- 环绕通知 --aop:around methodmyAround pointcut-refmyPointcut/aop:around/aop:aspect /aop:config SpringAOP_切点表达式 使用AspectJ需要使用切点表达式配置切点位置写法如下 标准写法访问修饰符 返回值 包名.类名.方法名(参数列表) 访问修饰符可以省略。 返回值使用 * 代表任意类型。 包名使用 * 表示任意包多级包结构要写多个 * 使用 *… 表示任意包结构 类名和方法名都可以用 * 实现通配。 参数列表 基本数据类型直接写类型引用类型写 包名.类名* 表示匹配一个任意类型参数… 表示匹配任意类型任意个数的参数 全通配 * *…*.*(…) SpringAOP_多切面配置 我们可以为切点配置多个通知形成多切面比如希望dao层的每个方法结束后都可以打印日志并发送邮件 编写发送邮件的通知 public class MyAspectJAdvice2 {// 后置通知public void myAfterReturning(JoinPoint joinPoint) {System.out.println(发送邮件);} }配置切面 !-- 通知对象 -- bean idmyAspectJAdvice classcom.itbaizhan.advice.MyAspectAdvice/bean bean idmyAspectJAdvice2 classcom.itbaizhan.advice.MyAspectAdvice2/bean !-- 配置AOP -- aop:config!-- 配置切面 --aop:aspect refmyAspectJAdvice!-- 配置切点 --aop:pointcut idmyPointcut expressionexecution(* *..*.*(..))/!-- 后置通知 --aop:after-returning methodmyAfterReturning pointcut-refmyPointcut//aop:aspectaop:aspect refmyAspectJAdvice2aop:pointcut idmyPointcut2 expressionexecution(* com.gb.dao.UserDao.*(..))/aop:after-returning methodmyAfterReturning pointcut-refmyPointcut2//aop:aspect /aop:configSpringAOP_注解配置AOP Spring可以使用注解代替配置文件配置切面 在xml中开启AOP注解支持 !-- 开启注解配置Aop --aop:aspectj-autoproxy/aop:aspectj-autoproxy在通知类上方加入注解 Aspect在通知方法上方加入注解 Before/AfterReturning/AfterThrowing/After/Around Aspect Component public class MyAspectJAdvice {Pointcut(execution(* com.gb.dao.UserDao.*(..)))public void point(){}// 后置通知AfterReturning(point())public void myAfterReturning(JoinPoint joinPoint) {System.out.println(切点方法名 joinPoint.getSignature().getName());System.out.println(目标对象 joinPoint.getTarget());System.out.println(打印日志 joinPoint.getSignature().getName() 方法被执行了);}Before(point())// 前置通知public void myBefore() {System.out.println(前置通知...);}AfterThrowing(value point(),throwing ex)// 异常通知public void myAfterThrowing(Exception ex) {System.out.println(异常通知...);System.err.println(ex.getMessage());}After(point())// 最终通知public void myAfter() {System.out.println(最终通知);}Around(point())// 环绕通知public Object myAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {System.out.println(环绕前);Object obj proceedingJoinPoint.proceed(); // 执行方法System.out.println(环绕后);return obj;} }SpringAOP_原生Spring实现AOP 除了AspectJSpring支持原生方式实现AOP。 引入依赖 !-- AOP -- dependencygroupIdorg.springframework/groupIdartifactIdspring-aop/artifactIdversion5.3.13/version /dependency编写通知类 package com.gb.advice;import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; import org.springframework.aop.AfterReturningAdvice; import org.springframework.aop.MethodBeforeAdvice; import org.springframework.aop.ThrowsAdvice;import java.lang.reflect.Method;public class SpringAop implements MethodBeforeAdvice, AfterReturningAdvice, ThrowsAdvice, MethodInterceptor {/*** 前置通知* param method 目标方法* param args 目标方法的参数列表* param target 目标对象* throws Throwable*/Overridepublic void before(Method method, Object[] args, Object target) throws Throwable {System.out.println(前置通知);}/*** 后置通知* 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(后置通知);}/*** 环绕通知* param invocation 目标方法* return* throws Throwable*/Overridepublic Object invoke(MethodInvocation invocation) throws Throwable {System.out.println(环绕前);Object proceed invocation.proceed();System.out.println(环绕后);return proceed;}/*** 异常通知* param ex 异常对象*/public void afterThrowing(Exception ex){System.out.println(发生异常了);} } Spring原生方式实现AOP时只支持四种通知类型 | 通知类型 | 实现接口 | |:--|:--| 前置通知 | MethodBeforeAdvice 后置通知 |AfterReturningAdvice 异常通知 |ThrowsAdvice 环绕通知 |MethodInterceptor编写配置类 ?xml version1.0 encodingUTF-8? beans xmlnshttp://www.springframework.org/schema/beansxmlns:contexthttp://www.springframework.org/schema/contextxmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xmlns:aophttp://www.springframework.org/schema/aopxsi: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 http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd!-- 包扫描 --context:component-scan base-packagecom.gb/context:component-scanbean idspringAop classcom.gb.advice.SpringAop/bean!-- 开启注解配置Aop --aop:aspectj-autoproxy proxy-target-classtrue/aop:aspectj-autoproxy!-- 配置代理对象 --bean iduserDaoProxy classorg.springframework.aop.framework.ProxyFactoryBean!-- 配置目标对象 --property nametarget refuserDao/property!-- 配置通知 --property nameinterceptorNameslistvaluespringAop/value/list/property!-- 代理对象的生成方式 true使用CGLib false使用原生JDK生成--property nameproxyTargetClass valuetrue/property/bean /beans编写测试类 public class UserDaoTest2 {Testpublic void testAdd(){ApplicationContext ac new ClassPathXmlApplicationContext(bean2.xml);UserDao userDao (UserDao)ac.getBean(userDaoProxy); // 获取的是代理对象userDao.update();} }SpringAOP_SchemaBased实现AOP SchemaBased(基础模式)配置方式是指使用Spring原生方式定义通知而使用AspectJ框架配置切面。 编写通知类 // Spring原生Aop的通知类 public class SpringAop2 implements MethodBeforeAdvice, AfterReturningAdvice, ThrowsAdvice, MethodInterceptor {/*** 前置通知* param method 目标方法* param args 目标方法的参数列表* param target 目标对象* throws Throwable*/Overridepublic void before(Method method, Object[] args, Object target) throws Throwable {System.out.println(前置通知);}/*** 后置通知* 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(后置通知);}/*** 环绕通知* param invocation 目标方法* return* throws Throwable*/Overridepublic Object invoke(MethodInvocation invocation) throws Throwable {System.out.println(环绕前);Object proceed invocation.proceed();System.out.println(环绕后);return proceed;}/*** 异常通知* param ex 异常对象*/public void afterThrowing(Exception ex){System.out.println(发生异常了);}}配置切面 ?xml version1.0 encodingUTF-8? beans xmlnshttp://www.springframework.org/schema/beansxmlns:contexthttp://www.springframework.org/schema/contextxmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xmlns:aophttp://www.springframework.org/schema/aopxsi: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 http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd!-- 包扫描 --context:component-scan base-packagecom.gb/context:component-scanbean idspringAop2 classcom.gb.advice.SpringAop2/bean!-- 配置切面 --aop:config!-- 配置切点--aop:pointcut idmyPointcut expressionexecution(* com.gb.dao.UserDao.*(..))/!-- 配置切面advice-ref通知对象 pointcut-ref切点 --aop:advisor advice-refspringAop2 pointcut-refmyPointcut//aop:config /beans测试 public class UserDaoTest3 {Testpublic void add() {ApplicationContext ac new ClassPathXmlApplicationContext(applicationContext4.xml);UserDao userDao (UserDao) ac.getBean(userDao);userDao.add();} }Spring整合MyBatis 我们知道使用MyBatis时需要写大量创建SqlSessionFactoryBuilder、SqlSessionFactory、SqlSession等对象的代码而Spring的作用是帮我们创建和管理对象所以我们可以使用Spring整合MyBatis简化MyBatis开发。 搭配环境 dependencies!-- mybatis --dependencygroupIdorg.mybatis/groupIdartifactIdmybatis/artifactIdversion3.5.7/version/dependency!-- mysql驱动包 --dependencygroupIdmysql/groupIdartifactIdmysql-connector-java/artifactIdversion8.0.26/version/dependencydependencygroupIdcom.alibaba/groupIdartifactIddruid/artifactIdversion1.1.21/version/dependency!-- spring --dependencygroupIdorg.springframework/groupIdartifactIdspring-context/artifactIdversion5.3.13/version/dependencydependencygroupIdorg.springframework/groupIdartifactIdspring-tx/artifactIdversion5.3.13/version/dependencydependencygroupIdorg.springframework/groupIdartifactIdspring-jdbc/artifactIdversion5.3.13/version/dependency!-- MyBatis与Spring的整合包该包可以让Spring创建MyBatis的对象 --dependencygroupIdorg.mybatis/groupIdartifactIdmybatis-spring/artifactIdversion2.0.6/version/dependency!-- junit,如果Spring5整合junit则junit版本至少在4.12以上 --dependencygroupIdjunit/groupIdartifactIdjunit/artifactIdversion4.12/versionscopetest/scope/dependency!-- spring整合测试模块 --dependencygroupIdorg.springframework/groupIdartifactIdspring-test/artifactIdversion5.3.13/version/dependency/dependencies编写配置文件 编写数据库配置文件db.properties jdbc.driverClassNamecom.mysql.cj.jdbc.Driver jdbc.urljdbc:mysql:///student jdbc.usernameroot jdbc.password521314创建MyBatis配置文件SqlMapConfig.xml数据源、扫描接口都交由Spring管理不需要在MyBatis配置文件中设置。 ?xml version1.0 encodingUTF-8? !DOCTYPE configurationPUBLIC -//mybatis.org//DTD Config 3.0//ENhttp://mybatis.org/dtd/mybatis-3-config.dtd configuration /configuration 创建Spring配置文件applicationContext.xml ?xml version1.0 encodingUTF-8? beans xmlnshttp://www.springframework.org/schema/beansxmlns:contexthttp://www.springframework.org/schema/contextxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi: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.gb/context:component-scan!-- 读取配置文件 --context:property-placeholder locationclasspath:db.properties/context:property-placeholder!-- 创建druid数据源对象 --bean iddataSource classcom.alibaba.druid.pool.DruidDataSourceproperty namedriverClassName value${jdbc.driverClassName}/propertyproperty nameurl value${jdbc.url}/propertyproperty nameusername value${jdbc.username}/propertyproperty namepassword value${jdbc.password}/property/bean!-- Spring创建封装过的SqlSessionFactory --bean idsqlSessionFactory classorg.mybatis.spring.SqlSessionFactoryBeanproperty namedataSource refdataSource/property/bean!-- Spring创建封装过的SqlSession -- !-- bean idsqlSession classorg.mybatis.spring.SqlSessionTemplate-- !-- constructor-arg namesqlSessionFactory refsqlSessionFactory/-- !-- /bean--bean idmapperScannerConfigurer classorg.mybatis.spring.mapper.MapperScannerConfigurerproperty namebasePackage valuecom.gb.dao/property/bean /beans编写持久层接口和service类 Repository public interface StudentDao {// 查询所有学生Select(select * from student)ListStudent findAll();// 添加学生Insert(insert into student values(null,#{name},#{sex},#{address}))void add(Student student); }Service public class StudentService {// SqlSession对象Autowiredprivate SqlSessionTemplate sqlSession;// 使用SqlSession获取代理对象public ListStudent findAllStudent(){StudentDao studentDao sqlSession.getMapper(StudentDao.class);return studentDao.findAll();} }整合Junit进行单元测试 引入Junit和Spring整合Junit依赖 !-- junit,如果Spring5整合junit则junit版本至少在4.12以上 -- dependencygroupIdjunit/groupIdartifactIdjunit/artifactIdversion4.12/versionscopetest/scope /dependency !-- spring整合测试模块 -- dependencygroupIdorg.springframework/groupIdartifactIdspring-test/artifactIdversion5.3.13/version /dependency编写测试类 // JUnit使用Spring方式运行代码即自动创建spring容器。 RunWith(SpringJUnit4ClassRunner.class) // 告知创建spring容器时读取哪个配置类或配置文件 // 配置类写法ContextConfiguration(classes配置类.class) ContextConfiguration(classpath:applicationContext.xml) public class StudentServiceTest {Autowiredprivate StudentService studentService;Testpublic void t1(){ListStudent studentList studentService.findStudenAll();studentList.forEach(System.out::println);}Testpublic void t2(){Student student new Student(龙傲天,男,荒芜大陆);studentService.addStudent(student);} }自动创建代理对象 Spring提供了MapperScannerConfigurer对象该对象可以自动扫描包创建代理对象并将代理对象放入容器中此时不需要使用SqlSession手动创建代理对象。 创建MapperScannerConfigurer对象 bean idmapperScannerConfigurer classorg.mybatis.spring.mapper.MapperScannerConfigurerproperty namebasePackage valuecom.gb.dao/property/beanService类直接使用代理对象即可 Service public class StudentService {// 直接注入代理对象Autowiredprivate StudentDao studentDao;// 直接使用代理对象public void addStudent(Student student){studentDao.add(student);} }Spring事务_事务简介 事务不可分割的原子操作。即一系列的操作要么同时成功要么同时失败。 开发过程中事务管理一般在service层service层中可能会操作多次数据库这些操作是不可分割的。否则当程序报错时可能会造成数据异常。 Spring事务_Spring事务管理方案 在Spring框架中提供了两种事务管理方案 编程式事务通过编写代码实现事务管理。声明式事务基于AOP技术实现事务管理。 在Spring框架中编程式事务管理很少使用Spring的声明式事务管理在底层采用了AOP技术其最大的优点在于无需通过编程的方式管理事务只需要在配置文件中进行相关的规则声明就可以将事务规则应用到业务逻辑中。 使用AOP技术为service方法添加如下通知 Spring事务_Spring事务管理器 Spring依赖事务管理器进行事务管理事务管理器即一个通知类我们为该通知类设置切点为service层方法即可完成事务自动管理。 由于不同技术操作数据库进行事务操作的方法不同。如JDBC提交事务是 connection.commit() MyBatis提交事务是 sqlSession.commit() 所以Spring提供了多个事务管理器。 事务管理器名称作用org.springframework.jdbc.datasource.DataSourceTransactionManager针对JDBC技术提供的事务管理器。适用于JDBC和MyBatis。org.springframework.orm.hibernate3.HibernateTransactionManager针对于Hibernate框架提供的事务管理器。适用于Hibernate框架。org.springframework.orm.jpa.JpaTransactionManager针对于JPA技术提供的事务管理器。适用于JPA技术。org.springframework.transaction.jta.JtaTransactionManager跨越了多个事务管理源。适用在两个或者是多个不同的数据源中实现事务控制。 我们使用MyBatis操作数据库接下来使用 DataSourceTransactionManager 进行事务管理。 引入依赖 !-- 事务管理 -- dependencygroupIdorg.springframework/groupIdartifactIdspring-tx/artifactIdversion5.3.13/version /dependency !-- AspectJ -- dependencygroupIdorg.aspectj/groupIdartifactIdaspectjweaver/artifactIdversion1.8.7/version /dependency引入约束 xmlns:aophttp://www.springframework.org/schema/aop xmlns:txhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd进行事务配置 !-- 进行事务配置 --tx:advice idtxAdvicetx:attributes!-- propagation:设置事务的传播方式 isolation:设置方法的事务隔离级别 --tx:method name* propagationREQUIRED isolationDEFAULT/!--设置查询方法为只读事务--tx:method namefind* read-onlytrue isolationREAD_UNCOMMITTED/tx:method/tx:attributes/tx:advice!-- 配置切面 --aop:configaop:pointcut idmyPoint expressionexecution(* com.gb.service.*.*(..))/aop:advisor advice-reftxAdvice pointcut-refmyPoint/aop:advisor/aop:configSpring事务_事务控制的API Spring进行事务控制的功能是由三个接口提供的这三个接口是Spring实现的在开发中我们很少使用到只需要了解他们的作用即可 PlatformTransactionManager接口 PlatformTransactionManager是Spring提供的事务管理器接口所有事务管理器都实现了该接口。该接口中提供了三个事务操作方法 TransactionStatus getTransactionTransactionDefinition definition获取事务状态信息。void commitTransactionStatus status事务提交void rollbackTransactionStatus status事务回滚 TransactionDefinition接口 TransactionDefinition是事务的定义信息对象它有如下方法 String getName()获取事务对象名称。int getIsolationLevel()获取事务的隔离级别。int getPropagationBehavior()获取事务的传播行为。int getTimeout()获取事务的超时时间。boolean isReadOnly()获取事务是否只读。 TransactionStatus接口 TransactionStatus是事务的状态接口它描述了某一时间点上事务的状态信息。它有如下方法 void flush() 刷新事务boolean hasSavepoint() 获取是否存在保存点boolean isCompleted() 获取事务是否完成boolean isNewTransaction() 获取是否是新事务boolean isRollbackOnly() 获取是否回滚void setRollbackOnly() 设置事务回滚 Spring事务_事务的相关配置 在tx:advice中可以进行事务的相关配置 tx:advice idtxAdvicetx:attributestx:method name*/tx:method namefind* read-onlytrue//tx:attributes /tx:advicetx:method 中的属性 name指定配置的方法。 * 表示所有方法 find* 表示所有以find开头的方法。read-only是否是只读事务只读事务不存在数据的修改数据库将会为只读事务提供一些优化手段会对性能有一定提升建议在查询中开启只读事务。timeout指定超时时间在限定的时间内不能完成所有操作就会抛异常。默认永不超时rollback-for指定某个异常事务回滚其他异常不回滚。默认所有异常回滚。no-rollback-for指定某个异常不回滚其他异常回滚。默认所有异常回滚。propagation事务的传播行为isolation事务的隔离级别 Spring事务_事务的传播行为 事务传播行为是指多个含有事务的方法相互调用时事务如何在这些方法间传播。 如果在service层的方法中调用了其他的service方法假设每次执行service方法都要开启事务此时就无法保证外层方法和内层方法处于同一个事务当中。 // method1的所有方法在同一个事务中 public void method1(){// 此时会开启一个新事务这就无法保证method1()中所有的代码是在同一个事务中method2();System.out.println(method1); } public void method2(){System.out.println(method2); }事务的传播特性就是解决这个问题的Spring帮助我们将外层方法和内层方法放入同一事务中。 传播行为介绍REQUIRED默认。支持当前事务如果当前没有事务就新建一个事务。这是最常见的选择。SUPPORTS支持当前事务如果当前没有事务就以非事务方式执行。MANDATORY支持当前事务如果当前没有事务就抛出异常。REQUIRES_NEW新建事务如果当前存在事务把当前事务挂起。NOT_SUPPORTED以非事务方式执行操作如果当前存在事务就把当前事务挂起。NEVER以非事务方式执行如果当前存在事务则抛出异常。NESTED必须在事务状态下执行如果没有事务则新建事务如果当前有事务则创建一个嵌套事务 Spring事务_事务的隔离级别 事务隔离级别反映事务提交并发访问时的处理态度隔离级别越高数据出问题的可能性越低但效率也会越低。 隔离级别脏读不可重复读幻读READ_UNCOMMITED读取未提交内容YesYesREAD_COMMITED读取提交内容NoYesREPEATABLE_READ重复读NoNoSERIALIZABLE可串行化NoNo 如果设置为DEFAULT会使用数据库的隔离级别。 SqlServer , Oracle默认的事务隔离级别是READ_COMMITEDMysql的默认隔离级别是REPEATABLE_READ Spring事务_注解配置声明式事务 注册事务注解驱动 !-- 注册事务注解驱动 -- tx:annotation-driven transactionmanagertransactionManager/tx:annotation-driven在需要事务支持的方法或类上加Transactional3 配置类代替xml中的注解事务支持在配置类上方写EnableTranscationManagement
http://www.w-s-a.com/news/583619/

相关文章:

  • 网站建设与维护 课件网页版qq安全中心登录入口
  • 做三个月网站广告收入dw如何制作网页
  • ...课程网站建设简介工信部 网站备案查询
  • 网站代码建设 实例企业网站建设大概的费用
  • 制作网站软件排行榜过年做啥网站致富
  • 哪里有做网站企业seo关键词优化
  • 上海金山网站建设公司手机淘宝客网站怎么做的
  • 网站开发需要公司做网站费用计入什么科目
  • 网站优化有哪些类型免费制作app的傻瓜软件
  • 如何做网站咨询wordpress get
  • 企业网站建设网站做网站用别人的图片
  • 站长统计代码个人网站源代码
  • 求推荐专门做借条的网站公众号排版编辑器
  • 动态做网站网站开发语言查询 蔡学镛
  • 莆田网站建设创意自助建站英文
  • cms系统创建静态网站龙岗网站建设哪家好
  • 自己做的网站被封了邢台规划局网站建设
  • 网站建设项目合同wordpress主题没法用
  • 个旧市哪里有做网站wordpress内页php页面
  • 程序员接活的平台网站互联网平台建设方案
  • 网站安全建设模板深圳企业管理咨询公司
  • 做网站 还是淘宝店wordpress分类链接后加
  • wordpress腾讯云 COSseo内容优化心得
  • 特价旅游机票网站建设i营销
  • 如何成立网站深圳创业项目
  • 建设商业网站惠州网站建设推荐乐云seo
  • 如何申请免费域名做网站免费推广神器
  • 自媒体人专用网站安岳网站建设
  • 特乐网站建设做网站推广要多少钱
  • 山东省建设安全生产协会网站义乌跨境电商公司前十名