首页 > 其他分享 >轻松掌握Spring:快速入门指南 (免费学习!!!)

轻松掌握Spring:快速入门指南 (免费学习!!!)

时间:2024-11-14 20:16:16浏览次数:3  
标签:指南 String Spring void public Bean class 入门

目录

一、Spring简单介绍

二、Java反射机制

三、Spring IOC机制

3.1 使用构造器来实例化Bean

3.2 使用静态工厂实例化Bean

3.3 使用实例工厂来实例化Bean

3.4 Spring IOC实现原理

3.5 Spring Bean的作用域

四、Spring AOP机制

4.1 相关概念

4.2 利用proxy实现AOP功能

4.3 利用CGLib实现AOP功能

4.4 Spring利用注解方式实现AOP

4.5 Spring利用xml配置文件实现AOP

五、Spring  中的事务管理 

        5.1  事务简介

        5.2  Spring 中的事务管理

        5.3  @Transactional


一、Spring简单介绍

spring是一个轻量级控制反转(IOC)和面向切面(AOP)的容器框架,它主要是为了解决企业应用开发的复杂性而诞生的

所谓IOC,对于spring框架来说,就是spring控制对象的生命周期和对象间的关系。IOC的另外一个名字叫做依赖注入(Dependency Injection),所谓依赖注入,就是由IOC容器在运行期间动态地将某种依赖关系注入到对象中。因此,依赖注入(DI)和控制反转(IOC)是从不同角度在描述同一件事情,指通过引入IOC容器,利用依赖关系注入的方式实现对象之间的解耦。二者在语义上区别在于:

  • IOC控制反转。说的是创建实例的控制权从代码控制剥离到IOC容器控制,实现就是在xml进行控制,侧重原理

  • DI依赖注入。说的是创建对象实例时,为这个对象注入属性值或其它对象实例,侧重实现

所谓AOP,即将系统分为系统服务和业务逻辑,主要意图是将日志记录、性能统计、异常处理等代码从业务逻辑中分离出来。通常通过AOP来处理一些具有横切性质的系统级服务,如事务管理、安全检查、缓存、对象池管理等,AOP已经成为一种非常有用的解决方案

spring是一个复杂、完整的框架体系,上述只是对spring的主要思想作了简要介绍。其中,IOC和AOP的实现都依赖与Java的反射机制,因此,接下来会先介绍一下什么是Java的反射机制

二、Java反射机制

Java语言允许通过程序化的方式间接对class的对象实例进行操作,class文件由类装载器装载后,在JVM中将形成一份描述class结构的元信息对象,通过该元信息对象可以获知class的结构信息,如构造函数、属性和方法

类装载器就是寻找类的字节码并构造出类在JVM内部表示的对象组件,主要工作由ClassLoader及其子类负责。ClassLoader是一个重要的Java运行时系统组件,它负责在运行时查找和装入class字节码文件。我们通过一个例子来进一步说明java反射机制

Car类:

public class Car {

    private String brand;
    private String color;
    private int maxSpeed;

    //1.默认构造函数
    public Car(){
        System.out.println("init car!!");
    }

    //2.带参构造函数
    public Car(String brand, String color, int maxSpeed){
        this.brand = brand;
        this.color = color;
        this.maxSpeed = maxSpeed;
    }

    //3.为带参方法
    public void introduce(){
        System.out.println("brand:" + brand + "; color:" + color + "; maxSpeed:" + maxSpeed);
    }

    public String getBrand() {
        return brand;
    }

    public void setBrand(String brand) {
        this.brand = brand;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public int getMaxSpeed() {
        return maxSpeed;
    }

    public void setMaxSpeed(int maxSpeed) {
        this.maxSpeed = maxSpeed;
    }
}

ReflectTest类:

public class ReflectTest {

    public static void main(String[] args) throws Throwable{
        Car car1 = initByDefaultConst();
        Car car2 = initByParamConst();
        car1.introduce();
        car2.introduce();
    }

    //通过无参构造器实例化对象并初始化
    public static Car initByDefaultConst() throws Throwable{
        //1.通过类装载器获取Car类对象
        ClassLoader loader = Thread.currentThread().getContextClassLoader();
        Class clazz        = loader.loadClass("springIOC.reflect.Car");

        //2.获取类的默认构造器对象并实例化Car
        Constructor cons   = clazz.getDeclaredConstructor((Class[]) null);
        Car car            = (Car)cons.newInstance();

        //3.通过反射方法获取属性
        Method setBrand = clazz.getMethod("setBrand", String.class);
        setBrand.invoke(car, "奔驰");
        Method setColor = clazz.getMethod("setColor", String.class);
        setColor.invoke(car, "黑色");
        Method setMaxSpeed = clazz.getMethod("setMaxSpeed", int.class);
        setMaxSpeed.invoke(car, 200);

        return car;
    }

    //通过有参构造器实例化对象并初始化
    public static Car initByParamConst() throws Throwable{
        //1.通过类装载器获取类对象
        ClassLoader loader = Thread.currentThread().getContextClassLoader();
        Class clazz        = loader.loadClass("springIOC.reflect.Car");

        //2.获取类的带有参数的构造器
        Constructor cons   = clazz.getDeclaredConstructor(new Class[]{String.class, String.class, int.class});

        //3.使用带有参数的构造器实例化对象
        Car car = (Car)cons.newInstance(new Object[]{"宝马", "绿色", 180});

        return car;
    }
}

运行结果如下:

这说明我们已经成功利用java的反射机制创建出了Car类的两个实例,并运行了它们的方法

三、Spring IOC机制

如前所述,Spring IOC机制指的是创建实例的控制权从代码控制剥离到IOC容器控制。而Spring初始化Bean共有三种方式,分别是使用构造函数来初始化Bean、使用静态工厂方式来初始化Bean以及使用实例工厂方式来初始化Bean。下面分别对这三种方式进行说明

3.1 使用构造器来实例化Bean

HelloWorld接口:

public interface HelloWorld {
    public void sayHello();
}

HelloWorld实现类:

public class HelloWorldImpl implements HelloWorld{

    private String message;

    public HelloWorldImpl(){
        this.message = "Hello World!";
    }

    public HelloWorldImpl(String message){
        this.message = message;
    }

    @Override
    public void sayHello() {
        System.out.println(message);
    }
}

配置文件:

<!--使用默认构造参数-->
<bean id="helloWorldWithNoArgs" class="springIOC.instanceA.HelloWorldImpl" />

<!--使用有参数构造函数-->
<bean id="helloWorldWithArgs" class="springIOC.instanceA.HelloWorldImpl">
      <!--指定构造器参数-->
      <constructor-arg index="0" value="Hello Args" />
</bean>

主函数:

import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {
    public static void main(String[] args){
        sayHelloWithArgs();
        sayHelloWithNoArgs();
    }

    //使用无参数构造器来实例化Bean
    public static void sayHelloWithNoArgs(){
        BeanFactory beanFactory = new ClassPathXmlApplicationContext("resource/conf-instanceA.xml");
        HelloWorld helloWorld   = beanFactory.getBean("helloWorldWithNoArgs", HelloWorld.class);
        helloWorld.sayHello();
    }

    //使用有参数构造器来实例化Bean
    public static void sayHelloWithArgs(){
        BeanFactory beanFactory = new ClassPathXmlApplicationContext("resource/conf-instanceA.xml");
        HelloWorld helloWorld   = beanFactory.getBean("helloWorldWithArgs", HelloWorld.class);
        helloWorld.sayHello();
    }
}

运行结果如下:

这说明我们已经成功通过Spring IOC机制的构造函数方式创建了HelloWorldImpl的两个实例

3.2 使用静态工厂实例化Bean

使用静态工厂的方式除了指定必须的class属性外,还要指定factory-method属性来实例化Bean的方法,而且使用静态工厂方法也允许指定方法参数。Spring IOC容器将调用此属性指定的方法来获取Bean
示例中,HelloWorld接口和HelloWorldImpl类和3.1节一样,HelloWorldInstanceFactory类如下:

public class HelloWorldInstanceFactory {

    public static HelloWorld newInstance(String message){

        return new HelloWorldImpl(message);
    }
}

配置文件如下:

<!--静态工厂方式-->
<bean id="helloWorldStaticFactory" class="springIOC.instanceB.HelloWorldInstanceFactory" factory-method="newInstance">
      <!--指定构造器参数-->
      <constructor-arg index="0" value="Hello Static Factory!" />
</bean>

主函数如下:

public class Main {
    public static void main(String[] args){
        helloWorldStaticFactory();
    }

    //使用静态工厂方法来实例化Bean
    public static void helloWorldStaticFactory(){
        //1.读取配置文件实例化一个IOC容器
        BeanFactory beanFactory = new ClassPathXmlApplicationContext("resource/conf-instanceB.xml");

        //2.从容器中获取Bean
        HelloWorld helloWorld   = beanFactory.getBean("helloWorldStaticFactory", HelloWorld.class);

        //3.执行业务逻辑
        helloWorld.sayHello();
    }
}

运行结果如下:

这说明我们已经成功通过Spring IOC机制的静态工程方式创建了HelloWorldImpl类的对象

3.3 使用实例工厂来实例化Bean

使用实例工厂方式不能指定class属性,此时必须使用factory-bean属性来指定工厂bean,factory-method属性来指定实例化bean的方法。同时,使用实例工厂方法允许指定方法参数
示例中,HelloWorld接口和HelloWorldImpl类和3.1节一样,HelloWorldInstanceFactory类如下:

public class HelloWorldInstanceFactory {

    public HelloWorld newInstance(String message) {
        return new HelloWorldImpl(message);
    }
}

xml配置文件如下:

<!--定义实例工厂Bean-->
<bean id="helloWorldInstanceFactory" class="springIOC.instanceC.HelloWorldInstanceFactory" />

<!--使用实例工程Bean创建Bean-->
<bean id="helloWorldInstance" factory-bean="helloWorldInstanceFactory" factory-method="newInstance">
      <constructor-arg index="0" value="Hello Instance Factory"></constructor-arg>
</bean>

运行结果如下:

这说明我们已经成功通过Spring IOC机制的实例工程方式创建了HelloWorldImpl类的对象

3.4 Spring IOC实现原理

Spring IOC的实现原理利用的是Java的反射机制,它的工厂类会帮我们完成配置文件的读取、利用反射机制注入对象等工作,我们可以通过Bean的名称来获取对应的对象
下面通过一个示例来简单展示来它的实现机制。首先创建一个JavaBean类:

public class JavaBean {

    private String userName;
    private String password;

    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;
    }
}

BeanFactory类:

public class BeanFactory {

    private Map<String, Object> beanMap = new HashMap<String, Object>();

    /**
     * bean工厂的初始化,通过xml文件给对象注入相关属性
     * @param xml xml配置文件
     */
    public void init(String xml){
        try{
            //1.创建读取配置文件的reader对象
            SAXReader reader = new SAXReader();

            //2.获取当前线程中的类装载器对象
            ClassLoader classLoader = Thread.currentThread().getContextClassLoader();

            //3.从class目录下获取指定的xml文件
            InputStream ins = classLoader.getResourceAsStream(xml);
            Document doc    = reader.read(ins);
            Element root    = doc.getRootElement();
            Element foo;

            //4.遍历xml文件中的bean实例
            for(Iterator i=root.elementIterator("bean"); i.hasNext();){
                foo = (Element) i.next();

                //5.针对每个bean实例,获取bean的属性id和class
                Attribute id  = foo.attribute("id");
                Attribute cls = foo.attribute("class");

                //6.利用java反射机制,通过class名称获取class对象
                Class bean = Class.forName(cls.getText());

                //7.获取对应class信息
                java.beans.BeanInfo info = java.beans.Introspector.getBeanInfo(bean);

                //8.获取其属性信息
                java.beans.PropertyDescriptor pd[] = info.getPropertyDescriptors();

                //9.创建一个对象,并在接下来的代码中为对象的属性赋值
                Object obj = bean.getDeclaredConstructor().newInstance();

                //10.遍历该bean的property属性
                for(Iterator ite=foo.elementIterator("property"); ite.hasNext();){
                    Element foo2 = (Element)ite.next();

                    //11.获取该property的name属性
                    Attribute name = foo2.attribute("name");
                    String   value = null;

                    //12.获取该property的子元素value的值
                    for(Iterator ite1=foo2.elementIterator("value"); ite1.hasNext();){
                        Element node = (Element)ite.next();
                        value = node.getText();
                        break;
                    }

                    //13.利用java的反射机制调用对象的某个set方法,并将值设置进去
                    for(int k=0; k<pd.length; k++){
                        if(pd[k].getName().equalsIgnoreCase(name.getText())){
                            Method mSet = null;
                            mSet = pd[k].getWriteMethod();
                            mSet.invoke(obj, value);
                        }
                    }
                }

                //14.将对象放入beanMap中,其中key为id值,value为对象
                beanMap.put(id.getText(), obj);
            }
        } catch (Exception e) {
            System.out.println(e.toString());
        }
    }

    public Object getBean(String beanName){
        Object obj = beanMap.get(beanName);

        return obj;
    }

    public static void main(String[] args){
        BeanFactory factory = new BeanFactory();
        factory.init("resource/config-realize.xml");
        JavaBean javaBean = (JavaBean)factory.getBean("javaBean");
        System.out.println("userName=" + javaBean.getUserName());
        System.out.println("password=" + javaBean.getPassword());
    }
}

xml配置文件:

<bean id="javaBean" class="springIOC.realize.JavaBean">
      <property name="userName">
          <value>周杰伦</value>
      </property>
      <property name="password">
          <value>19790118</value>
      </property>
</bean>

3.5 Spring Bean的作用域

Spring Bean中所说的作用域,在xml配置文件中使用"scope"配置,指其创建的Bean对象相对于其它Bean对象的请求可见范围。常见的有以下两种:

  • singleton:Spring IOC中只会存在一个共享的Bean实例,所有对Bean的请求,只要id相匹配,则只会返回Bean的同一个实例

  • prototype:每次对该Bean进行请求时,都会创建一个新的Bean实例

下面通过一个例子来说明这两种作用域的区别。首先创建一个Car类:

public class Car {

    private String color;
    private String brand;
    private double price;

    public double getPrice(){
        return price;
    }

    public void setPrice(double price){
        this.price = price;
    }

    public String getBrand(){
        return brand;
    }

    public void setBrand(String brand){
        this.brand = brand;
    }

    public String getColor(){
        return color;
    }

    public void setColor(String color){
        this.color = color;
    }
}

Boss类:

public class Boss {

    private String name;
    private Car car;

    public Boss(){}

    public Car getCar(){
        return car;
    }

    public void setCar(Car car){
        this.car = car;
    }

    @Override
    public String toString(){
        return "name:" + name + "\n car:" + car;
    }
}

xml配置文件:

<bean id="car" class="springIOC.scope.Car" scope="singleton" />
<bean id="boss1" class="springIOC.scope.Boss" p:car-ref="car" />
<bean id="boss2" class="springIOC.scope.Boss" p:car-ref="car" />
<bean id="boss3" class="springIOC.scope.Boss" p:car-ref="car" />

主函数:

public class Main {

    public static void main(String[] args){
        BeanFactory beanFactory = new ClassPathXmlApplicationContext("resource/conf-scope.xml");
        Boss boss1 = beanFactory.getBean("boss1", Boss.class);
        Boss boss2 = beanFactory.getBean("boss2", Boss.class);
        Boss boss3 = beanFactory.getBean("boss3", Boss.class);
        System.out.println(boss1.getCar());
        System.out.println(boss2.getCar());
        System.out.println(boss3.getCar());
    }
}

当scope="singleton"运行结果如下:

三个对象的地址是一样的,证明三次对Bean的请求返回的是同一个实例

当scope="prototype"运行结果如下:

三个对象的地址是不一样的,证明三次对Bean的请求返回的是不同的实例

四、Spring AOP机制

4.1 相关概念

概念含义
连接点程序执行的某个特定位置,比如类初始化前、初始化后,方法执行前、执行后
切点通过切点来定位特殊的连接点
增强织入到目标类连接点上的一段代码
目标对象增强对象的织入目标类
引介引介是一种特殊的增强,它为类添加一些属性和方法
织入将增强添加到目标类具体连接点的过程
代理一个类被AOP织入增强后,会产生一个结果类,该类是融合了原类和增强逻辑的代理类
切面由切点和增强组成,既包括了增强逻辑的定义,也包括了连接点的定义

4.2 利用proxy实现AOP功能

本小节是单纯针对AOP思想的实现,而不局限于Apring AOP。对于proxy类有一个使用前提,就是目标对象必须要实现接口,否则不能使用这个方法。下面通过一个示例来说明如何通过proxy类来实现AOP思想

StudengInterface接口:

public interface StudentInterface {

    public void print();
}

StudentBean类:

public class StudentBean implements StudentInterface{

    private String name;

    public StudentBean(){}

    public StudentBean(String name){
        this.name = name;
    }

    @Override
    public void print() {
        System.out.println("Hello World!");
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

ProxyFactory类:

public class ProxyFactory implements InvocationHandler {

    private Object stu;

    public Object createStudentProxy(Object stu){
        this.stu = stu;

        return Proxy.newProxyInstance(stu.getClass().getClassLoader(), stu.getClass().getInterfaces(), this);
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        StudentBean s = (StudentBean)stu;
        Object object = null;
        if(s.getName()!=null){
            object = method.invoke(stu, args);
        } else {
            System.out.println("名称为空,代理类已经拦截!");
        }

        return object;
    }

主函数:

public class Main {

    public static void main(String[] args){

        StudentInterface s1  = new StudentBean();
        ProxyFactory factory = new ProxyFactory();
        StudentInterface s2  = (StudentInterface)factory.createStudentProxy(s1);
        s2.print();
    }
}

运行结果如下:

4.3 利用CGLib实现AOP功能

CGLib(Code Generation Library)是一个开源项目,它是一个强大的、高性能、高质量的Code生成类库,可以在运行期间扩展Java类与实现Java接口。利用proxy创建的代理类和目标对象必须实现同一接口,使用CGLib则继承了目标对象

Student类:

public class StudentBean {

    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public StudentBean(){}
    public StudentBean(String name){
        this.name=name;
    }

    public void print() {
        System.out.println("Hello World!");
    }
}

CGLibProxyFactory类:

public class CGLibProxyFactory implements MethodInterceptor {

    private Object object;
    public Object createStudent(Object object){
        this.object = object;
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(object.getClass());
        enhancer.setCallback(this);

        return enhancer.create();
    }

    public Object getObject() {
        return object;
    }

    public void setObject(Object object) {
        this.object = object;
    }

    @Override
    public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
        StudentBean stu = (StudentBean)object;
        Object result   = null;
        if(stu.getName()!=null){
            result = methodProxy.invoke(object, args);
        }else{
            System.out.println("该方法已被拦截!");
        }

        return result;
    }
}

主函数:

public class Main {

    public static void main(String[] args){
        StudentBean s1 = (StudentBean)(new CGLibProxyFactory()).createStudent(new StudentBean());
        StudentBean s2 = (StudentBean)(new CGLibProxyFactory()).createStudent(new StudentBean("Leon"));

        s1.print();
        s2.print();
    }
}

运行结果如下:

4.4 Spring利用注解方式实现AOP

Student类:

public class Student {

    public String print(String name){
        System.out.println(name);

        return "Hello World";
    }
}

StuInterceptor类:

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;

@Aspect
public class StuInterceptor {

    @Pointcut("execution(* springAOP.aspect.Student.print(..))")
    public void printMethod(){
    }

    @Before("printMethod()")
    public void printBeforeAdvice(){
        System.out.println("printBeforeAdvice!");
    }

    @AfterReturning(pointcut="printMethod()", returning="flag")
    public void printAfterAdvice(String flag){
        System.out.println("printAfterAdvice()!" + flag);
    }

    @After("printMethod()")
    public void printFinallyAdvice(){
        System.out.println("printFinally" +
                "Advice!");
    }

    @Around("printMethod() && args(name)")
    public Object printAroundAdvice(ProceedingJoinPoint pjp, String name) throws Throwable{
        Object obeject = null;
        if(name.equals("Jay Chou"))
            pjp.proceed();
        else
            System.out.println("print()方法已经被拦截!!");

        return obeject;
    }
}

xml配置:

<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
       http://www.springframework.org/schema/aop/spring-aop-3.1.xsd">

       <aop:aspectj-autoproxy />
       <bean id="stuInterceptor" class="springAOP.aspect.StuInterceptor"></bean>
       <bean id="stu" class="springAOP.aspect.Student"></bean>
</beans>

主函数:

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {

    public static void main(String[] args){

        ApplicationContext ctx = new ClassPathXmlApplicationContext("resource/conf-aspect.xml");
        Student stu = (Student)ctx.getBean("stu");
        stu.print("Jay Chou");
    }
}

运行结果如下:

4.5 Spring利用xml配置文件实现AOP

Student类和4.4小节的Student类一样。StuInterceptor类如下:

import org.aspectj.lang.ProceedingJoinPoint;

public class StuInterceptor {

    public void printMethod(){
    }

    public void printBeforeAdvice(){
        System.out.println("printBeforeAdvice!");
    }

    public void printAfterAdvice(String flag){
        System.out.println("printAfterAdvice()!" + flag);
    }

    public void printFinallyAdvice(){
        System.out.println("printFinally" + "Advice!");
    }

    public Object printAroundAdvice(ProceedingJoinPoint pjp, String name) throws Throwable{
        Object obeject = null;
        if(name.equals("Jay Chou"))
            pjp.proceed();
        else
            System.out.println("print()方法已经被拦截!!");

        return obeject;
    }
}

xml配置文件如下:

<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
       http://www.springframework.org/schema/aop/spring-aop-3.1.xsd">

    <aop:aspectj-autoproxy />
    <bean id="interceptor" class="springAOP.xml.StuInterceptor"></bean>
    <bean id="stu" class="springAOP.xml.Student"></bean>

    <aop:config>
        <aop:aspect id="stuInterceptor" ref="interceptor">
            <aop:before
                pointcut="execution(* springAOP.xml.Student.print(..))"
                method="printBeforeAdvice" />
            <aop:after-returning
                pointcut="execution(* springAOP.xml.Student.print(..)) and args(flag)"
                method="printAfterAdvice" arg-names="flag"/>
            <aop:after
                pointcut="execution(* springAOP.xml.Student.print(..))"
                method="printFinallyAdvice" />
            <aop:around
                pointcut="execution(* springAOP.xml.Student.print(..)) and args(name)"
                method="printAroundAdvice" arg-names="pjp,name" />
        </aop:aspect>
    </aop:config>
</beans>

主函数:

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {

    public static void main(String[] args){

        ApplicationContext ctx = new ClassPathXmlApplicationContext("resource/conf-xml.xml");
        Student stu = (Student)ctx.getBean("stu");
        stu.print("Jay Chou");
    }
}

运行结果如下:

五、Spring  中的事务管理 

5.1  事务简介

•    事务管理是企业级应用程序开发中必不可少的技术,  用来确保数据的完整性和一致性. 
•    事务就是一系列操作数据库的动作, 它们被当做一个单独的工作单元. 这些动作要么全部完成, 要么全部不起作用
•    事务的四个关键属性(ACID)  (重点 重点 重点  重要事情说三遍!!!)


–    原子性(atomicity): 事务是一个原子操作, 由一系列动作组成. 事务的原子性确保动作要么全部完成(要么成功)要么完全不起作用(要么失败).
–    一致性(consistency): 一旦所有事务动作完成, 事务就被提交(commit). 数据和资源就处于一种满足业务规则的一致性状态中.
–    隔离性(isolation): 可能有许多事务会同时处理相同的数据, 因此每个事物都应该与其他事务隔离开来, 防止数据损坏.
–    持久性(durability): 一旦事务完成, 无论发生什么系统错误, 它的结果都不应该受到影响. 通常情况下, 事务的结果被写到持久化存储器中.

事务管理的问题
 

puhlic void purchase ( string isbn,string usernarme ) {
connection conn = null;
try {
conn = datasource. getconnection ( ) ;conn. setAutoCormit (false ) ;
// .. .
conn. commit( ) ;
}catch (sQLException e){
e. printstackTrace ( ) ;
if(conn != null) {
try {
conn.rollback ( ) ;
}catch ( SQLException e1) {
e1.printstackTrace ( );
}
}
throw new RuntimeException (e);
fina1ly{
if ( conn != nu11) {
try {
conn.close ( ):
}eateh (sQLException e){
e.printstackTrace ( ) ;
}

5.2  Spring 中的事务管理

•    作为企业级应用程序框架, Spring 在不同的事务管理 API 之上定义了一个抽象层. 而应用程序开发人员不必了解底层的事务管理 API, 就可以使用 Spring 的事务管理机制.
•    Spring 既支持编程式事务管理, 也支持声明式的事务管理. 
•    编程式事务管理: 将事务管理代码嵌入到业务方法中来控制事务的提交和回滚. 在编程式管理事务时, 必须在每个事务操作中包含额外的事务管理代码. 
•    声明式事务管理: 大多数情况下比编程式事务管理更好用. 它将事务管理代码从业务方法中分离出来, 以声明的方式来实现事务管理. 事务管理作为一种横切关注点, 可以通过 AOP 方法模块化. Spring 通过 Spring AOP 框架支持声明式事务管理.
Spring 中的事务管理器
•    Spring 从不同的事务管理 API 中抽象了一整套的事务机制. 开发人员不必了解底层的事务 API, 就可以利用这些事务机制. 有了这些事务机制, 事务管理代码就能独立于特定的事务技术了.
•    Spring 的核心事务管理抽象是
•    它为事务管理封装了一组独立于技术的方法. 无论使用 Spring 的哪种事务管理策略(编程式或声明式), 事务管理器都是必须的.
Spring 中的事务管理器的不同实现 - *重要*
•                   在应用程序中只需要处理一个数据源, 而且通过 JDBC 存取
•     : 在 JavaEE 应用服务器上用 JTA(Java Transaction API) 进行事务管理
•     :用 Hibernate 框架存取数据库
•    ……
•    事务管理器以普通的 Bean 形式声明在 Spring IOC 容器中(事务交给IOC容器来管理)

5.3  @Transactional

用@Transactional注解声明式地管理事务
·除了在带有切入点,通知和增强器的Bean 配置文件中声明事务外,
Spring还允许简单地用@Transactional注解来标注事务方法.·为了将方法定义为支持事务处理的,可以为方法添加
@Transactional注解.根据Spring AOP基于代理机制,只能标注公有方法.
。可以在方法或者类级别上添加@Transactional注解.当把这个注
解应用到类上时,这个类中的所有公共方法都会被定义成支持事务处理的.
。在Bean配置文件中只需要启用<tx:annotation-drien>元素,并
为之指定事务管理器就可以了.
。如果事务处理器的名称是transactionManager,就可以在
<tx:annotation-driven>元秦中省略 transaction-manager属性.这个元秦会自动检测该名称的事务处理器
 

 

标签:指南,String,Spring,void,public,Bean,class,入门
From: https://blog.csdn.net/qq_41320700/article/details/143779152

相关文章

  • 30道Spring高频面试题,学完吊打面试官(实用干货!!!)
    1、什么是Spring框架?Spring框架有哪些主要模块?答:Spring框架是一个为Java应用程序的开发提供了综合、广泛的基础性支持的Java平台。Spring帮助开发者解决了开发中基础性的问题,使得开发人员可以专注于应用程序的开发。Spring框架本身亦是按照设计模式精心打造,这使得我们可......
  • IDEA 如何手动创建spring boot工程
    步骤创建Maven工程引入依赖提供启动类一,创建maven工程newModules选择Maven起名选择骨架quickstart检查maven工程坐标一般不用改二,引入依赖坐标打开pom文件1,让当前工程继承一个副工程<parent><groupId>org.springframework.boot</groupId><artifactId>spring-......
  • SpringBoot快速入门
    一、SpringBoot简介SpringBoot是由Pivotal团队提供的全新框架,旨在简化Spring应用的初始搭建以及开发过程。它基于SpringFramework构建,但并不是Spring的替代者或精简版本,而是为了让程序员更好地使用Spring。SpringBoot通过提供默认配置和“习惯优于配置”的理念,使得开发者......
  • 程序员如何入门?零基础入门到精通,收藏这一篇就够了
    以下内容仅供参考建议。做任何事情,最关键的是先入门,所谓的入门,是你进入一家公司,然后开始给人家干活,并且能够提供合格的交付件,这就算入门了。那么做编程到底到了哪个地步才算入门呢?我的目的就是在你一行代码还没写的时候,给一些建议。不管任何企业,厉害的人应该是主动的帮企业......
  • FastHTML快速入门:服务器渲染超媒体应用的利器
    项目简介FastHTML是一个Python库,它将Starlette、Uvicorn、HTMX和fastcore的FT"FastTags"融合在一起,用于创建服务器渲染的超媒体应用程序。FastHTML类本身继承自Starlette,并增加了基于装饰器的路由、Beforeware、自动将FT渲染为HTML等功能。写作FastHTML应用时需记住的事......
  • 企业级工位管理:Spring Boot技术突破
    2相关技术2.1MYSQL数据库MySQL是一个真正的多用户、多线程SQL数据库服务器。是基于SQL的客户/服务器模式的关系数据库管理系统,它的有点有有功能强大、使用简单、管理方便、安全可靠性高、运行速度快、多线程、跨平台性、完全网络化、稳定性等,非常适用于Web站点或者其他......
  • 工位管理优化:Spring Boot企业级系统
    3系统分析3.1可行性分析通过对本企业级工位管理系统实行的目的初步调查和分析,提出可行性方案并对其一一进行论证。我们在这里主要从技术可行性、经济可行性、操作可行性等方面进行分析。3.1.1技术可行性本企业级工位管理系统采用SSM框架,JAVA作为开发语言,是基于WEB平台的......
  • 基于SpringBoot的信息技术知识竞赛系统
    关注底部领取源码源码编号:S321源码名称:基于SpringBoot的信息技术知识竞赛系统用户类型:双角色,用户、管理员主要技术:Java、Vue、ElementUl、SpringBoot运行环境:Windows/Mac、JDK1.8及以上运行工具:IDEA/Eclipse数 据 库:MySQL5.7及以上版本数据库表数量:16张表是否有......
  • Spring Boot编程训练系统:核心特性与实现策略
    3系统分析3.1可行性分析通过对本编程训练系统实行的目的初步调查和分析,提出可行性方案并对其一一进行论证。我们在这里主要从技术可行性、经济可行性、操作可行性等方面进行分析。3.1.1技术可行性本编程训练系统采用SSM框架,JAVA作为开发语言,是基于WEB平台的B/S架构系统......
  • Spring Boot编程训练系统:从概念到实现
    2相关技术2.1MYSQL数据库MySQL是一个真正的多用户、多线程SQL数据库服务器。是基于SQL的客户/服务器模式的关系数据库管理系统,它的有点有有功能强大、使用简单、管理方便、安全可靠性高、运行速度快、多线程、跨平台性、完全网络化、稳定性等,非常适用于Web站点或者其他......