前言

大家好,这次爆肝两天给大家总结了一份对于Spring框架的知识点,创作不易,点个赞再看吧!

1.Spring概述

1.1Spring框架是什么?

Spring框架是一个凋谢源代码的J2EE应用程序框架,由Rod Johnson 发动,是针对bean的生命周期进行治理的轻量级容器(lightweight container)。 Spring解决了开发者在J2EE开发中遇到的许多常见的问题,提供了功能强大IOC、AOP及Web MVC等性能。Spring能够独自利用于构筑应用程序,也能够和Struts、Webwork、Tapestry等泛滥Web框架组合应用,并且能够与 Swing等桌面应用程序AP组合。因而, Spring不仅仅能利用于J2EE应用程序之中,也能够利用于桌面应用程序以及小应用程序之中。Spring框架次要由七局部组成,别离是 Spring Core、 Spring AOP、 Spring ORM、 Spring DAO、Spring Context、 Spring Web和 Spring Web MVC。

1.spring全家桶: spring ,springmvc,spring boot,spring cloud

2.spring:呈现是在2002左右,解决企业开发的难度。加重对我的项目模块之间的治理,类和类之间的治理,帮 助开发人员创建对象,治理对象之间的关系。spring核心技术ioc ,aop。能实现模块之间,类之间的解耦合。

1.2Spring的长处

1.轻量

spring框架应用的jar比拟小,都在1M一下或者几百kb。spring外围性能的所需的jar总共在3M左右。spring框架运行时占用的资源少,运行效率高,不依赖别的jar。

2.针对接口编程,解耦合

spring提供了Ioc管制反转,由容器治理对象,对象的依赖关系。原来在程序代码中的对象创立形式,现状由容器实现。对象之间的依赖解耦合。

3.AOP编程的反对

通过Spring提供的AOP性能,不便进行面向切面的编程,许多不容易用传统0OP实现的性能能够通过AOP轻松应酬,在Spring中,开发人员能够从繁冗的事务管理代码中解脱进去,通过申明式形式灵便地进行事务的治理,进步开发效率和品质。

4.不便集成各种优良的框架

Spring不排挤各种优良的开源框架,相同Spring能够升高各种框架的应用难度,Spring提供了对各种优良框架( 如Struts,Hibernate、MyBatis) 等的间接反对。简化框架的应用。Spring像插线板一样, 其余框架是插头,能够容易的组合到一起。须要应用哪个框架,就把这个插头放入插线板。不须要能够轻易的移除。

1.3Spring的体系结构

2.Ioc管制反转

管制反转(Ioc,Inversion of Control),是一个概念,一种思维。指将传统上由程序代码间接操控的对象调用权交给容器,通过容器来实现对象的拆卸和治理。管制反转就是对对象控制权的转移,从程序代码自身反转到了内部容器。通过容器实现对象的创立,属性赋值,依赖的治理。

loc的实现:IoC是一个概念,是一种思维,其实现形式多种多样。以后比拟风行的实现形式是依赖注入。利用宽泛。

依赖: classA 类中含有classB的实例,在classA中调用classB的办法实现性能,即classA对classB有依赖。

依赖注入: DI(Dependency Injection),程序代码不做定位查问,这些工作由容器自行实现。

依赖注入DI是指程序运行过程中,若须要调用另一个对象帮助时,毋庸在代码中创立被调用者,而是依赖于内部容器,由内部容器创立后传递给程序。

Spring的依赖注入对调用者与被调用者简直没有任何要求,齐全反对对象之间依赖关系的治理。

Spring框架应用依赖注入(DI) 实现IoC。

Spring容器是一个超级大工厂,负责创立、治理所有的Java对象,这些Java对象被称为Bean。Spring 容器治理着容器中Bean之间的依赖关系,Spring 应用“依赖注入”的形式来治理Bean之间的依赖关系。应用loC实现对象之间的解耦合。

2.1开发工具筹备

利用maven工具,创立

实现步骤:1.创立maven我的项目2.退出maven的依赖        spring的依赖,版本5.3.7        junit依赖3.创立类(接口和它的实现类),和没有应用框架一样,就是一般的类。4.创立spring须要应用的配置文件    申明类的信息。这些类由spring创立和治理5.测试spring创立的对象。

2.2Sprig的第一个程序

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"       xsi:schemaLocation="http://www.springframework.org/schema/beans       http://www.springframework.org/schema/beans/spring-beans.xsd">    <!--通知spring创建对象    申明bean,通知spring要创立某个类的对象    id是对象的自定义名称(惟一值)。spring通过这个名称找到对象    class:类的全限定名称(不能是接口,因为spring是反射机制)    spring就实现SomeService someService = new SomeServiceImpl();    spring是把创立好的对象放到了map中,spring框架中有一个map寄存对象的。    springMap.put(id的值,对象)    例如 springMap.put("someService",new someServiceImpl());    一个bean标签只申明一个对象    -->    <bean id="someService" class="cqutlc.service.Impl.someServiceImpl"></bean>    <!--spring能创立一个非自定义的类-->    <bean id="mydate" class="java.util.Date"/></beans><!--spring的配置文件1.beans是根标签,spring中把Java对象成为bean2.spring-beans.xsd是束缚文件,和mybatis指定的相似-->
package cqutlc;import cqutlc.service.Impl.someServiceImpl;import cqutlc.service.someService;import org.junit.Test;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class Test1 {    @Test    public void test1(){        someService someService=new someServiceImpl();        someService.doSome();    }    /*spring默认创建对象的工夫:在创立spring的容器时,他会创立配置文件中的所有对象*/    @Test    public void test2(){        //应用spring容器创立的对象        //1.指定spring配置文件的名称        String config="beans.xml";        //2.创立示意spring容器的对象,ApplicationContext        //ClassPathXmlApplicationContext;示意从类门路中加载spring的配置文件        ApplicationContext ac=new ClassPathXmlApplicationContext(config);        //3.从容器中获取某个对象,你要调用对象的办法,        //getBean("配置文件中的bena的id值");        someService service=(someService)ac.getBean("someService");        //应用spring创立好的对象        service.doSome();    }    /*获取spring容器中的Java对象的信息*/    @Test    public void test3(){        String config="beans.xml";        ApplicationContext ac=new ClassPathXmlApplicationContext(config);        //应用spring提供的办法,获取容器中定义的对象的数量        int num=ac.getBeanDefinitionCount();        System.out.println(num);        //容器中每个定义的对象的名称        String[] names= ac.getBeanDefinitionNames();        for (String name : names) {            System.out.println(name);        }    }}

2.3基于XML的DI

在spring配置文件中,给Java对象的属性赋值。

di:依赖注入,示意创建对象,给属性赋值。

di的实现语法:
1.在spring配置文件中,应用标签和属性实现,叫做基于xml的di实现
2.应用spring中的注解进行属性的赋值,叫做基于注解的di实现。

di的语法分类
1.set注入(设置注入): spring调用类的set办法,在set办法能够实现属性的赋值

2.结构注入,spring调用类的有参构造方法,创建对象。在构造方法中实现赋值。

set注入实例剖析

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">    <!--申明student对象    注入:就是赋值的意思    简略类型:spring中规定Java的根本数据类型和string类型都是简略类型。    di:给属性赋值    1.set注入(设置注入):spring调用类的set办法,你能够在set办法中实现属性赋值        利用property    -->    <bean id="student" class="cqutlc.ba01.Student">        <property name="name" value="李四"/><!--调用setName...-->        <property name="age" value="20"/>认准set办法    </bean></beans>

当属性为援用类型时

2.援用类型的set注入:spring调用set办法--><bean id="student" class="cqutlc.ba02.Student">    <property name="name" value="李四"/><!--调用setName...-->    <property name="age" value="24"/>    <property name="school" ref="school"/></bean><bean id="school" class="cqutlc.ba02.School">    <property name="name" value="cqut"/>    <property name="address" value="cq"/></bean>

结构注入

得有结构参数

2.结构注入 spring调用类的有参数构造方法,在创建对象的同时给属性赋值结构注入应用--><bean id="student" class="cqutlc.ba03.Student">    <constructor-arg name="name" value="lc"/>    <constructor-arg name="age" value="19"/>    <constructor-arg name="school" ref="myschool"/></bean><bean id="myschool" class="cqutlc.ba03.School">    <property name="name" value="cqut"/>    <property name="address" value="cq"/></bean>

援用类型的主动注入

byName和byType

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">    <!--    援用类型的主动注入:spring框架依据某些规定能够给援用类型赋值。不必你再给援用类型赋值了    应用的规定罕用的是    1.byName(按名称注入):Java类中援用类型的属性名和spring容器中(配置文件)<bean>的id名称一样。                          且数据类型统一,这样的容器中的bean,spring可能赋值给援用类型。    2.byType(按类型注入):Java类中援用类型的数据类型和spring容器中(配置文件)<bean>的class是同源关系。    <bean id="" class="" outowire="byType">    -->    <bean id="student" class="cqutlc.ba04.Student" autowire="byName">        <property name="name" value="李四"/><!--调用setName...-->        <property name="age" value="24"/>        <!--<property name="school" ref="school"/>-->    </bean>    <bean id="school" class="cqutlc.ba04.School">        <property name="name" value="cqut"/>        <property name="address" value="cq"/>    </bean></beans>

多个配置文件的劣势

1.每个文件的大小比一个文件要小得多。效率高

2.防止多人竞争带来的抵触

多文件的调配形式:

1.按功能模块,一个模块一个配置文件。

2.按类的性能,数据库相干,做事务处理的,做service的。

蕴含关系的配置门路

2.4基于注解的DI

通过注解实现Java对象的创立,属性赋值

应用注解的步骤

  • 退出maven的依赖spring-context,在你退出spring-context的同时,间接退出spring-aop的依赖。应用注解必须应用spring-aop依赖
  • 在类中退出spring的注解(多个不同性能的注解)
  • 在spring的配置文件中,退出一个组件扫描器的标签,阐明注解在你的我的项目中的地位。

学习的注解有:
1.@Component 2.@Repository 3.@Service 4.@Controller 5.@Value 6.@Autowired 7.@Resource

简略类型

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"       xmlns:context="http://www.springframework.org/schema/context"       xsi:schemaLocation="http://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">    <!--申明组件扫描器(component-scan),    组件就是Java对象,所以就是找Java对象    base-package:指定注解在你的我的项目中的包名    component-scan工作形式:spring会扫描遍历base-package指定的包    把包中和子包中的所有类,找到类中的注解,依照注解的性能创建对象和给属性赋值。    -->  <context:component-scan base-package="cqutlc.ba01"/></beans>
package cqutlc.ba01;import org.springframework.stereotype.Component;/** @Component:创建对象的,等同于<bean>的性能* 属性value: 就是对象的名称,也就是bean的id值,value值是惟一的,创立的对象在整个spring容器中就一个* 地位:在类的下面写注解* *///等同于<bean id="myStudent" class="cqutlc.ba01.Student"/>//@Component(value = "myStudent")//省略value//@Component("myStudent")//不指定对象名称,由spring提供默认名称(首字母小写类名)@Componentpublic class Student {    private String name;    private Integer age;    public void setName (String name) {        this.name = name;    }    public void setAge (Integer age) {        this.age = age;    }    @Override    public String toString () {        return "Student{" +                "name='" + name + '\'' +                ", age=" + age +                '}';    }}
package cqutlc;import cqutlc.ba01.Student;import org.junit.Test;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class test1 {    @Test    public void test(){        String config="applicationContext.xml";        ApplicationContext ac=new ClassPathXmlApplicationContext (config);        //从容器中获取对象        Student student=(Student) ac.getBean ("student");        System.out.println (student);    }}
* spring中和@Component性能统一,创建对象的注解还有:* @Repository(用在长久层上):放在dao的实现类下面,* 示意创立dao对象,dao对象是能拜访数据库的。(长久层注解)** @Service(用在业务层类的下面):放在service的实现类下面,* 创立service对象,service对象是做业务解决的,能够有事物等性能的。** @Controller(用在控制器的下面):放在控制器(处理器)类的下面,创立控制器对象的,* 控制器对象能够接管用户提交的参数和显示申请的处理结果。** 以上三个注解的应用语法和@Component是一样的,都可能创建对象,然而这三个注解还有额定的性能----给我的项目分层

指定多个包的三种形式

  • 应用屡次组件扫描器标签,指定不同的包
  • 应用分隔符(分号或者逗号)分隔多个包名
  • 指定父包

援用类型

@Autowired:spring框架提供的注解,实现援用类型的赋值spring中通过注解给援用类型赋值,应用的是主动注入,反对byName和byType@Autowired默认应用@byType主动注入

地位:

1.在属性定义的下面,无需set办法,举荐应用。被援用的类必须提前利用@Component注解标识。

2.在set办法的下面

属性:required,是一个boolean类型的,默认是true,示意援用类型失败时,程序报错并终止运行。要是false则失常运行,赋值为null,最好用true,能够及时发现谬误!

如果要应用byName的形式

1.在属性的下面加上@Autowired

2.在属性下面退出@Qualifier(vlaue=“bean的id”):示意应用指定名字的bean实现赋值。

@Resource:来自于JDK中的注解,spring框架提供了对这个注解性能的反对。能够用它给援用类型赋值,应用的也是主动注入原理,反对byName,byType。默认是byName

地位:

1.在属性定义的下面,无需set办法,举荐应用

2.在set办法的下面先应用byName主动注入,如果失败了就会再应用byType

如何只应用byName?

须要新减少一个属性name name的值为bean的id名称

3.AOP面向切面编程

3.1动静代理

动静代理是指:程序在整个运行过程中基本就不存在指标类的代理类,指标对象的代理只是由代理生成工具(不是实在定义的类)在程序运行时由JVM依据反射等机制动静生成,代理对象与指标对象的代理关系在程序运行时确定。

实现形式:
jdk动静代理, 应用jdk中的Proxy, Method, Invocai tonHanderl创立代理对象。jdk动静代理要求指标类必须实现接口。
cglib动静代理:第三方的工具库,创立代理对象,原理是继承。通过继承指标类,创立子类。子类就是代理对象。要求指标类不能是final的,办法也不能是final的。

动静代理的作用:

  • 在指标类源代码不变的状况下,加强性能
  • 缩小代码的反复
  • 专一业务逻辑代码
  • 解耦合,让你的业务性能和日志,事务非事务性能拆散

3.2AOP简介

AOP (Aspect Orient Programming),面向切面编程。面向切面编程是从动静角度思考程序运行过程。

AOP底层,就是采纳动静代理模式实现的。采纳了两种代理: JDK的动静代理,与CGLIB的动静代理。

AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,可通过运行期动静代理实现程序性能的对立保护的一种技术。AOP是Spring框架中的一个重要内容。利用AOP能够对业务逻辑的各个局部进行隔离,从而使得业务逻辑各局部之间的耦合度升高,进步程序的可重用性,同时进步了开发的效率。(动静代理的规范化,把动静代理的实现步骤,形式都定义好了,让开发人员用一种对立的办法,应用动静代理)。
切面:给你的指标类减少的性能,就是切面,什么日志等(切面的特点:个别都是非业务办法,独立应用的。)

面向切面编程,就是将穿插业务逻辑封装成切面,利用AOP容器的性能将切面织入到主业务逻辑中。所谓穿插业务逻辑是指,通用的、与主业务逻辑无关的代码,如安全检查、事务、日志、缓存等。
若不应用AOP,则会呈现代码纠缠,即穿插业务逻辑与主业务逻辑混合在一起。这样,会使主业务逻辑变的混淆不清。

如何了解面向切面编程?

  • 须要在剖析我的项目性能时,找出切面。
  • 正当的安顿切面的执行工夫(在指标办法前呢,还是后呢)
  • 正当的平安切面执行地位,在哪个类,哪个办法减少加强

3.3AOP编程术语

1.Aspect:切面,示意加强的性能,就是一堆代码,实现某个性能。(非业务性能,可独立执行。如:日志,统计信息,权限验证等)

2.JoinPoint:连接点,连贯你的业务办法和切面地位。其实就是某个类中的业务办法。

3.Pointcut:切入点,指多个连接点办法的汇合。

4.指标对象:给哪个类的办法减少性能,这个类就是指标对象。

5.Advice:告诉,告诉示意切面性能执行的工夫。

一个切面有三个要害的因素:

  • 切面的性能代码,切面干什么
  • 切面的执行地位,应用Pointcut示意切面执行地位
  • 切面执行工夫,应用advice示意工夫。

3.4AspectJ对AOP的实现

aop的实现:aop是一个标准,是一个动静的一个规范化,一个规范。

aop的技术实现框架:

1.spring:spring在外部实现了aop标准,能做aop的工作。

2.aspectJ:一个开源的专门做aop的框架。spring框架中集成了aspectJ框架,通过spring就能够应用aspectJ的性能了。

aspectJ框架实现有两种形式:1.应用xml的配置文件(配置全局事务) 2.应用注解,个别都用注解

3.5学习AspectJ框架的应用

如何示意切面的执行工夫?
注解示意:1.@Before 2.@AfterReturning 3.@Around 4.@AfterThrowing 5.@After

如何示意切面执行的地位?
应用的是切入点表达式。

表达式原型为:

execution(modifiers-pattern? ret-type-pattern         declaring-type-pattern?name-pattern(param-pattern)         throws-pattern?)

解释:

  • modifiers-pattern 拜访权限类型
  • ret-type-pattern 返回值类型
  • declaring-type-pattern 包名类名
  • name-pattern(param-pattern) 办法名(参数类型和参数个数)
  • throws-pattern 抛出异样类型

?示意可选局部

以上表达式共分为四个局部 execution(拜访权限 办法返回值 办法申明(参数)异样类型)

切入点表达式要匹配的对象就是指标办法的办法名。所以,execution 表达式中显著就是办法的签名。留神,表达式中彩色文字示意可省略局部,各局部间用空格离开。在其中能够应用以下符号:

Aspect的开发环境

应用aspectJ框架实现aop应用aop:目标是给曾经存在的一些类和办法,减少额定的性能,前提是不扭转原来的类的代码。框架的应用步骤:1.新建maven我的项目2.退出依赖    spring依赖 aspectJ依赖 junit单元测试3.创立指标类:接口和他的实现类    要做的是给类中的办法去减少性能4.创立切面类:一般类        1.在类的下面退出@Aspect        2.在类中去定义方法---要执行的性能代码        3.在办法的下面退出aspectJ中的告诉注解,例如@Before          还须要指定切入点表达式execution()5.创立spring的配置文件,在文件中申明对象,把对象交给容器对立治理   申明对象能够应用注解或者xml配置文件   申明指标对象   申明切面类对象   申明aspectJ框架中的主动代理生成器标签(用来实现代理对象的主动创立性能的)6.创立测试类,从spring容器中获取指标对象(实际上是代理对象)。    通过代理执行办法,实现aop的性能加强

@Before实现的一个例子

package cqutlc.ba01;public interface SomeSevice {    void doSome(String name,Integer age);}package cqutlc.ba01;//指标类public class SomeSeviceImpl implements SomeSevice {    @Override    public void doSome (String name, Integer age) {        //给doSome办法减少一个性能,在doSome办法执行之前,输入办法的执行工夫        System.out.println ("指标办法执行");    }}package cqutlc.ba01;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Before;import java.util.Date;/**@Aspect:aspectJ框架中的注解,用来示意以后类是切面类* 地位:类定义的下面* */@Aspectpublic class MyAspect {    /*    * 定义方法:实现切面性能的、    * 办法的定义要求:    * 1.公共办法    * 2.没有返回值3.办法名自定义4.办法能够有参数也能够没有参数,有几个参数类型能够应用()    * */    /*@Before 前置告诉注解    * 属性:value,切入点表达式,示意切面的性能执行的地位    * 特点:在指标办法之前先执行,不会扭转指标办法的执行后果,不会影响指标办法的执行    * */    @Before (value = "execution(public void *..SomeSeviceImpl.doSome(..))")    public void myBefore(){        //性能代码        System.out.println ("工夫:"+new Date ());    }}
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"       xsi:schemaLocation="http://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">    <!--把对象交给spring容器,由容器对立创立和治理对象-->    <!--申明指标对象-->    <bean id="someService" class="cqutlc.ba01.SomeSeviceImpl"/>    <!--申明切面类对象-->    <bean id="myAspect" class="cqutlc.ba01.MyAspect"/>    <!--申明主动代理生成器:应用aspectJ框架外部的性能,创立指标对象的代理对象    创立代理对象是在内存中实现的,批改指标对象的内存中的构造,创立为代理对象    所以指标对象就是被批改后的代理对象    aspectj-autoproxy:会把spring容器中的所有的指标对象,一次性都生成代理对象。    -->    <aop:aspectj-autoproxy/></beans>
package cqutlc.ba01;import org.junit.Test;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class test1 {    @Test    public void test1(){        String config="applicationContext.xml";        ApplicationContext ac=new ClassPathXmlApplicationContext (config);        SomeSevice proxy=(SomeSevice)ac.getBean ("someService");        //通过代理的对象执行办法,实现目标办法执行时,加强了性能。        proxy.doSome ("lisi",20);    }}

JoinPoint

指定告诉办法中的参数

joinpoint:业务办法,要退出切面性能的业务办法

作用是:能够在告诉办法中获取办法执行时的信息,例如,办法名称,办法的实参。

如果你的切面性能中须要用到办法的信息,就退出joinpoint

这个joinpoint参数的值是由框架赋予,必须是第一个地位的参数。

@Aspectpublic class MyAspect {        @Before (value = "execution(public void *..SomeSeviceImpl.doSome(..))")    public void myBefore(JoinPoint jp){        //获取办法的残缺定义        System.out.println("办法的定义:"+jp.getSignature());        System.out.println("办法的名称:"+jp.getSignature().getName());        //获取办法的实参        Object[] args= jp.getArgs();        for(Object arg: args){            System.out.println("参数="+arg);        }        //性能代码        System.out.println ("工夫:"+new Date ());    }}

@AfterReturning

package cqutlc.ba02;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.annotation.AfterReturning;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Before;import java.util.Date;/**@Aspect:aspectJ框架中的注解,用来示意以后类是切面类* 地位:类定义的下面* */@Aspectpublic class MyAspect {    /*    * 后置告诉定义方法:实现切面性能的、    * 办法的定义要求:    * 1.公共办法    * 2.没有返回值3.办法名自定义4.办法有参数,举荐应用object,参数名自定义    * */    /*    * @AfterReturning    * 属性:    * 1.value:切入点表达式    * 2.returning:自定义的变量,用来示意指标办法的返回值,自定义变量名必须和告诉办法的形参名一样    * 特点:    * 1.在指标办法之后执行的    * 2.可能取得指标办法的返回值,能够依据这个返回值做不同的解决性能    *   Object res = doOther();    * 3.能够批改这个返回值。    * */    @AfterReturning(value = "execution(* *..SomeSeviceImpl.doOther(..))",            returning = "res")    public void myAfterReturing(Object res){        //Object res :是指标办法执行后的返回值,依据返回值做你的切面的性能解决        System.out.println ("后置告诉,获取的返回值是"+res);        if (res.equals ("abc")){            res="hi";        }else        {        }    }}

@Around盘绕告诉-加强办法有ProceedingJoinPoint参数

package cqutlc.ba03;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.Around;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Before;import java.util.Date;/**@Aspect:aspectJ框架中的注解,用来示意以后类是切面类* 地位:类定义的下面* */@Aspectpublic class MyAspect {   /*   * 盘绕告诉定义方法的格局   * 1.public   * 2.有一个返回值 object   * 3.办法名称自定义   * 4.办法有参数,固定的 ProceedingJoinPoint   *   * */   /*@Around   特点:   1.性能最强的告诉   2.在指标办法前和后都能够退出性能   3.控制目标办法是否被调用履行   4.批改原来的指标办法的执行后果,影响最初的调用后果   盘绕告诉等同于jdk动静代理,InvocationHandler接口   参数:ProceedingJoinPoint 就等同于Method   作用:执行指标办法的执行后果,能够被批改。   盘绕告诉:常常做事务,在指标办法之前开启事务,执行指标办法,在指标办法之后提交事务   * */   @Around (value = "execution(* *..SomeServiceImpl.doFirst(..))")   public Object myAround(ProceedingJoinPoint pjp) throws Throwable {       String name="";       Object[] args =pjp.getArgs ();       if (args!=null&&args.length>1){           Object arg= args[0];           name=(String)arg;       }       //在指标办法前或者后加性能       //实现盘绕告诉       Object result=null;       System.out.println ("盘绕告诉在指标办法之前"+new Date ());       if ("zhangsan".equals (name)){           //1.实现目标办法的调用           result= pjp.proceed ();//method.invoke,object result=doFirst();       }       System.out.println ("盘绕告诉在指标办法之后,提交事务");       return  result;   }}
package cqutlc.ba03;import org.junit.Test;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class test1 {    @Test    public void test1(){        String config="applicationContext.xml";        ApplicationContext ac=new ClassPathXmlApplicationContext (config);        SomeService proxy=(SomeService)ac.getBean ("someService");        String str=proxy.doFirst ("lc",19);    }}

@Pointcut定义切入点

当较多的告诉加强办法应用雷同的execution切入点表达式时,编写、保护均较为麻烦。
AspectJ提供了@Pointcut注解,用于定义execution切入点表达式。其用法是,将@Pointcut注解在一个办法之上,当前所有的execution的value属性值均可应用该办法名作为切入点。代表的就是@Pointcut定义的切入点。这个应用@Pointcut注解的办法个别应用private 的标识办法,即没有理论作用的办法。

属性 :value切入点表达式

地位:自定义的办法的下面

特点:当应用@Pointcut定义在一个办法的下面,此时这个办法的名称就是切入点表达式的别名,其余的告诉中,value属性就能够应用这个办法名称代替切入点表达式。

@Pointcut(value="execution(* *..SomeServiceImpl.doOther(..))")private void mypt(){    //无需代码}

有接口也能够应用cglib代理

在xml中配置<aop:aspectj-autoproxy proxy-target-class="true"/>示意通知框架,你要应用cglib代理。

4.Spring集成MyBatis

把mybatis和spring框架集成在一起,像一个框架一样应用。

用的技术是:IOC

为什么ioc能把spring和mybatis集成在一起?是因为ioc能创建对象,能够把mybatis创立的对象交给spring对立创立,开发人员从spring中获取对象。开发人员不必同时面对两个或多个框架了,就面对一个spring就行了。

mybatis应用步骤:咱们会应用独立的连接池类替换掉mybatis中自带的连接池,把连接池类也交给spring创立

spring须要创立的对象有:

  • 独立的连接池类的对象,应用阿里的druid连接池
  • SqlSessionFactory对象
  • 创立dao对象

    spring和mybatis集成步骤1.新建maven我的项目2.退出依赖  spring依赖 mybatis依赖 mysql驱动 spring的事务依赖 mybatis和spring集成的依赖(SqlSessionFactory)3.创立实体类4.创立dao接口和mapper文件5.创立mybatis主配置文件6.创立service接口和实现类,属性是dao7.创立spring的配置文件:申明mybatis的对象交给spring创立  1.数据源 dataSource  2.SqlSessionFactory  3.Dao对象  4.申明自定义的service8.创立测试类,获取service对象,通过service调用dao实现数据库的拜访

spring配置文件:

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">        <!--申明数据源DataSource,作用是连贯数据库的-->    <bean id="myDataSource" class="com.alibaba.druid.pool.DruidDataSource"              init-method="init" destroy-method="close">            <!--set注入给DruidDataSource提供连贯数据库信息-->            <property name="url" value="jdbc:mysql://localhost:3306/MySql            ?useUnicode=true&amp;characterEncoding=utf8&amp;serverTimezone=GMT"/><!--setUrl注入-->            <property name="username" value="root"/>            <property name="password" value="131138"/>            <property name="maxActive" value="20"/>    </bean>    <!--申明的是mybatis中提供的SqlSessionFactoryBean类,这个类外部创立SqlSessionFactory-->    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">        <!--set注入,把数据库连接池付给了dataSource-->        <property name="dataSource" ref="myDataSource"/>        <!--mybatis主配置文件的地位        configLocation属性是Resource类型,读取配置文件        它的赋值,应用的是value,指定门路的文件,应用  classpath:示意文件的地位        -->        <property name="configLocation" value="classpath:mybatis.xml"/>    </bean>    <!--创立dao对象,应用SqlSession的getMapper(studentDao.class)    MapperScannerConfigurer:在外部调用getMapper()生产每个dao接口的代理对象。    -->    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">        <!--指定sqlSessionFactory对象的id-->        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>        <!--指定包名,包名是dao接口所在的包名        MapperScannerConfigurer会扫描这个包中的所有接口,把每个接口都执行一次getMapper办法        失去每个接口的dao对象,创立好的dao对象放入到spring容器中        -->        <property name="basePackage" value="cqutlc.dao"/>    </bean>    <!--申明service-->    <bean id="studentService" class="cqutlc.service.Impl.StudentServiceImpl">        <property name="studentDao" ref="studentDao"/>    </bean></beans>

mybatis配置文件:

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE configuration        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"        "http://mybatis.org/dtd/mybatis-3-config.dtd"><configuration>    <!--日志-->    <settings>        <setting name="logImpl" value="STDOUT_LOGGING"/>    </settings>    <!--设置别名-->    <typeAliases>            <!--name所在包的门路-->        <package name="cqutlc.domain"/>    </typeAliases>    <!--sql mapper映射文件的地位-->    <mappers>        <!--name是包名-->        <package name="cqutlc.dao"/>    </mappers></configuration>

测试下:

package cqutlc;import cqutlc.dao.studentDao;import cqutlc.domain.Student;import cqutlc.service.Impl.StudentServiceImpl;import cqutlc.service.StudentService;import org.junit.Test;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;import java.util.List;public class test1 {    @Test    public void test(){        String config="applicationContext.xml";        ApplicationContext ac=new ClassPathXmlApplicationContext (config);        //获取spring容器中dao对象       studentDao studentDao=(studentDao) ac.getBean ("studentDao");        Student student=new Student (1005,"lc","444@qq.com",20);        int nums=studentDao.insertStudent (student);        //spring和mybatis整合在一起应用,事务是主动提交的,无需执行SqlSession.commit();        System.out.println (nums);    }    @Test    public void test2(){        String config="applicationContext.xml";        ApplicationContext ac=new ClassPathXmlApplicationContext (config);        StudentService studentService=(StudentService) ac.getBean ("studentService");        Student student=new Student (1006,"jkl","555@qq.com",20);        int nums=studentService.addStudent (student);        System.out.println (nums);    }    @Test    public void test3(){        String config="applicationContext.xml";        ApplicationContext ac=new ClassPathXmlApplicationContext (config);        StudentService studentService=(StudentService) ac.getBean ("studentService");        List<Student> students =studentService.queryStudents ();        for (Student student : students) {            System.out.println (student);        }    }}

5.Spring事务

5.1spring的事务管理

事务本来是数据库中的概念,在Dao层。然而个别状况下,须要将事务晋升到业务层,即Service层。这样做是为了可能应用事务的个性来治理具体的业务。

5.2spring事务管理API

事务的超时工夫:示意一个办法的最长执行工夫,如果办法执行时超过工夫,就进行事务回滚。

单位:秒,整数,默认-1

事务的流传行为

管制业务办法是否有事务,有的话是什么样的事务。

7个流传行为:示意你的业务办法调用时,事务在办法之间是如何应用的。

PROPAGATION_REQUIRED:指定的办法必须在事务内执行,若以后存在事务,就退出到以后事务中,若以后没有事务,则创立一个新事务。这种流传行为是最常见的抉择,也是spring默认的事务流传行为。

PROPAGATION_REQUIRES_NEW:指定的办法反对以后事务,但若以后没有事务,也能够也非事务形式执行。

PROPAGATION_SUPPORTS:总是创立一个新事务,若以后存在事务,就将以后事务挂起,直到新事务执行结束。

总结spring事务:

1.治理事务的是,事务管理和它的实现类

2.spring的事务是一个对立的模型。

指定要应用的事务管理器实现类,应用 bean

指定哪些类,哪些办法须要退出事务管理性能

指定办法须要的隔离级别和流传行为,超时。

5.3程序举例环境搭建

模仿一个销售零碎

package cqutlc.service;import cqutlc.dao.GoodsDao;import cqutlc.dao.SaleDao;import cqutlc.domain.Goods;import cqutlc.domain.Sale;import cqutlc.excep.NotEnoughException;public class BuyGoodsServiceImpl implements BuyGoodsService {    private SaleDao saleDao;    private GoodsDao goodsDao;    public void setSaleDao (SaleDao saleDao) {        this.saleDao = saleDao;    }    public void setGoodsDao (GoodsDao goodsDao) {        this.goodsDao = goodsDao;    }    /**/    @Override    public void buy (Integer goodsId, Integer nums) {        System.out.println ("buy办法的开始");        //记录销售信息        Sale sale=new Sale ();        sale.setGid (goodsId);        sale.setNums (nums);        saleDao.insertSale (sale);        //更新库存        Goods goods=goodsDao.selectGoods (goodsId);        if (goods==null){            throw new NullPointerException ("编号是:"+goodsId+"商品不存在");        }else if(goods.getAmount ()<nums) {            //库存有余            throw new NotEnoughException("编号是:"+goodsId+"库存有余!");        }        Goods buyGoods=new Goods ();        buyGoods.setId (goodsId);        buyGoods.setAmount (nums);        goodsDao.updateGoods (buyGoods);        System.out.println ("buy办法的完结");    }}

5.4应用spring的事务注解治理事务

两种处理事务的办法:

1.适宜于中小我的项目应用的:注解办法

spring框架本人用aop实现给业务办法减少事务的性能,应用 @Transactional注解减少事务

应用@Transactional的步骤

1.须要申明事务管理器对象

<bean id="xx" class="DataSourceTransactionManager">

2.开启事务注解驱动,通知spring框架,我要应用注解的形式治理事务。

spring应用aop机制,创立@Transactional所在的类代理对象,给办法退出事务的性能。

spring给业务办法退出事务:在你的业务办法执行之前,先开启事务,在业务办法执行完结后提交或者回滚事务,应用aop的盘绕告诉

3.在办法上退出@Transactional

<!--应用spring的事务处理--><!--申明事务管理器--><bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">    <!--连贯的数据库,制订数据源-->    <property name="dataSource" ref="myDataSource"/></bean><!--2.开启事务注解驱动,通知spring应用注解治理事务,创立代理对象transactionManager:事物管理器对象id--><tx:annotation-driven transaction-manager="transactionManager"/>
/** rollbackFor示意产生指定的异样肯定回滚* */@Transactional(        propagation = Propagation.REQUIRED,        isolation = Isolation.DEFAULT,        readOnly = false,        rollbackFor = {                NullPointerException.class,NotEnoughException.class        })@Override....省略(同上

5.5应用AspectJ的AOP配置管理事务

适宜大型项目,有很多的类,办法,须要大量的配置事务,应用aspectJ框架性能,在spring配置文件中申明类,办法须要的事务。这种形式业务办法和事务配置齐全拆散。

实现步骤:都是在xml配置文件中实现。

1.要应用的是aspectJ框架须要退出对应的依赖。

2.申明事务管理器对象

<bean id="xx" class="DataSourceTransactionManager">

3.申明办法须要的事务类型(配置办法的事物属性【隔离级别,流传行为,超时】)

4.配置aop,哪些类须要创立代理。

6.Spring与Web

web我的项目中容器对象只须要创立一次,把容器对象放入到全局作用域ServletContext中。

怎么实现:

应用监听器,当全局作用域对象被创立时,创立容器存入ServletContext

监听器作用:

1.创立容器对象,执行ApplicationContext ac=new ClassPathXmlApplicationContext (config);

2.把容器对象放入到ServletContext,ServletContext.setAttribute(key,ac)

监听器能够本人创立也能够用框架写好的 ContextLoaderListener

web.xml文件的配置

<?xml version="1.0" encoding="UTF-8"?><web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"         version="4.0">    <servlet>        <servlet-name>RegisterServlet</servlet-name>        <servlet-class>cqutlc.controller.RegisterServlet</servlet-class>    </servlet>    <servlet-mapping>        <servlet-name>RegisterServlet</servlet-name>        <url-pattern>/registerServlet</url-pattern>    </servlet-mapping>    <!--注册监听器ContextLoaderListener    监听器被创建对象后,会读取/WEB-INF/spring.xml    能够批改默认的文件地位,应用context-param从新指定文件的地位    配置监听器:目标是创立容器对象,创立了容器对象,就能把spring.xml配置文件中的所有对象都创立好    用户发动申请就能够间接调用对象了。    -->    <context-param>        <param-name>contextConfigLocation</param-name>        <param-value>classpath:spring.xml</param-value>    </context-param>    <listener>        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>    </listener></web-app>

spring配置文件

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">        <!--申明数据源DataSource,作用是连贯数据库的-->    <bean id="myDataSource" class="com.alibaba.druid.pool.DruidDataSource"              init-method="init" destroy-method="close">            <!--set注入给DruidDataSource提供连贯数据库信息-->            <property name="url" value="jdbc:mysql://localhost:3306/MySql            ?useUnicode=true&amp;characterEncoding=utf8&amp;serverTimezone=GMT"/><!--setUrl注入-->            <property name="username" value="root"/>            <property name="password" value="131138"/>            <property name="maxActive" value="20"/>    </bean>    <!--申明的是mybatis中提供的SqlSessionFactoryBean类,这个类外部创立SqlSessionFactory-->    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">        <!--set注入,把数据库连接池付给了dataSource-->        <property name="dataSource" ref="myDataSource"/>        <!--mybatis主配置文件的地位        configLocation属性是Resource类型,读取配置文件        它的赋值,应用的是value,指定门路的文件,应用  classpath:示意文件的地位        -->        <property name="configLocation" value="classpath:mybatis.xml"/>    </bean>    <!--创立dao对象,应用SqlSession的getMapper(studentDao.class)    MapperScannerConfigurer:在外部调用getMapper()生产每个dao接口的代理对象。    -->    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">        <!--指定sqlSessionFactory对象的id-->        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>        <!--指定包名,包名是dao接口所在的包名        MapperScannerConfigurer会扫描这个包中的所有接口,把每个接口都执行一次getMapper办法        失去每个接口的dao对象,创立好的dao对象放入到spring容器中        -->        <property name="basePackage" value="cqutlc.dao"/>    </bean>    <!--申明service-->    <bean id="studentService" class="cqutlc.service.Impl.StudentServiceImpl">        <property name="studentDao" ref="studentDao"/>    </bean></beans>

RegisterServlet类

package cqutlc.controller;import cqutlc.domain.Student;import cqutlc.service.StudentService;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;import org.springframework.web.context.WebApplicationContext;import org.springframework.web.context.support.WebApplicationContextUtils;import javax.servlet.ServletContext;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;public class RegisterServlet extends HttpServlet {    protected void doPost (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {        request.setCharacterEncoding("UTF-8");        String strId=request.getParameter ("id");        String strName=request.getParameter ("name");        String strEmail=request.getParameter ("email");        String strAge=request.getParameter ("age");        //创立spring的容器对象        //String config="spring.xml";        //ApplicationContext ac=new ClassPathXmlApplicationContext (config);        /*WebApplicationContext ac=null;        //获取servletContext中的容器对象,创立好的容器对象,拿来就用        String key=WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE;        Object attr= getServletContext ().getAttribute (key);        if (attr!=null){            ac=(WebApplicationContext)attr;        }*/        WebApplicationContext ac=null;        ServletContext sc=getServletContext ();        ac=WebApplicationContextUtils.getRequiredWebApplicationContext (sc);        System.out.println ("容器对象的信息=="+ac);        //获取service        StudentService studentService=(StudentService) ac.getBean ("studentService");        Student student=new Student ();        student.setId (Integer.parseInt (strId));        student.setName (strName);        student.setEmail (strEmail);        student.setAge (Integer.parseInt (strAge));        studentService.addStudent (student);        //给一个后果页面        request.getRequestDispatcher ("/result.jsp").forward (request,response);    }    protected void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {    }}
protected void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {}

到这里就完结了,如果有什么疑难,欢送评论,一起学习,一起提高O(∩_∩)O 下次想看我总结什么呢,能够在评论留言哦