欢迎您访问365答案网,请分享给你的朋友!
生活常识 学习资料

SSM框架中项目模块配置Controller层:Spring容器

时间:2023-07-29
目录

Spring

Spring简介Ioc控制反转

Ioc的概念Spring的配置文件Spring容器创建对象的特点DI注入

基于XML的DI基于注解的DI AOP面向切面编程

AOP的概念AOP的作用AOP的术语AOP技术思想的实现

Apsectj Spring集成MyBatisSpring事务

Spring的事务概念Spring事务管理器Spring的事务定义Spring注解管理事务AspectJ的AOP配置事务管理 Spring

Spring框架由Rod Johnson开发,2004年发布了Spring框架的第一版。Spring是一个从实际开发中抽取出来的框架,因此它完成了大量开发中的通用步骤,留给开发者的仅仅是与特定应用相关的部分,从而大大提高了企业应用的开发效率。

Spring简介

作用:为代码“解耦合”,降低代码间的耦合度(符合软件工程中的高内聚、低耦合的特点),让对象和对象(模块和模块)之间关系不是通过代码关联,而是通过配置来说明。

Spring根据代码的功能特点,使用Ioc降低业务对象之间耦合度,Ioc使得主业务在相互调用的过程中,不用再自己维护关系了,即不用再自己创建要使用的对象了,而是由Spring容器统一管理,自动注入,即赋值。而AOP使得系统级服务得到了最大复用,且不用再由程序员手工将系统级服务“混杂”到主业务逻辑中了,而是由Spring容器统一完成织入。

官网:

Spring安装包:

- spring-framework-5.2.5.RELEASE- docs # 相关文档- javadoc-api # 相关api- kdoc-api- spring-framework-reference # 开发手册- libs # 源码- spring-model-5.2.5.RELEASE.jar # 相关模块的字节码.class文件- spring-model-5.2.5.RELEASE-javadoc.jar # 相关模块的开发文档- spring-model-5.2.5.RELEASE-sources.jar # 相关模块的源文件.java- schema # 相关模块的约束文件

Spring优点

轻量针对接口编程、解耦合AOP编程的支持方便集成各种优秀框架 Ioc控制反转 Ioc的概念

概念:Ioc,Inversion of Control,控制反转,是一个理论,把对象的创建、属性赋值,对象的声明周期都交给代码以外的容器管理。

Ioc分为控制和反转

控制:对象创建、属性赋值,对象的声明周期反转:把开发人员管理对象的权限转移给了代码之外的容器实现,由容器完成对象的管理。正转:开发人员在代码中,使用new构造方法创建对象。

Ioc的实现

依赖注入:DI,Dependency Injection,程序只需要提供要使用的对象的名称即可,对象如何创建,如何从容器中查找,获取都由容器内部自己实现 Spring的配置文件

<?xml version="1.0" encoding="UTF-8"?>

Spring的标准配置文件

根标签是beansbeans后面是约束文件说明,beans里面是bean声明bean是java对象,Spring容器创建的java对象

创建对象并调用接口方法

package org.bjpowernode;import org.bjpowernode.service.SomeService;import org.bjpowernode.service.impl.SomeServiceImpl;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class AppMain { public static void main(String[] args) { // SomeService service = new SomeServiceImpl(); Impl一般指接口实现类 // service.doSome(); String config = "beans.xml"; // 创建容器对象, ApplicationContext表示spring容器对象,通过ctx获取某个Java对象 ApplicationContext ctx = new ClassPathXmlApplicationContext(config); // 从容器中获取指定名称的对象,使用getBean("id") SomeService service = (SomeService)ctx.getBean("someService"); // 调用对象的方法,接口中的方法 service.doSome(); }}

Spring容器创建对象的特点

Spring创建对象特点:

Spring创建对象调用的构造函数默认是无参构造,如果定义了有参构造,则再定义无参构造.

创建Spring容器对象的时候,会读取配置文件,创建文件中声明所有的的Java对象,即new ClassPathXmlApplicationContext(config);

优点:获取对象的速度快,因为对象已经创建好了

缺点:占用内存

String对象存在Spring内部的map中,并从map进行获取对象(可以调用ApplicationContext接口里面的方法试一试)

创建非自定义类对象

DI注入 基于XML的DI

Spring调用类的五参数构造方法,创建对象,对象创建后给属性赋值

使用xml配置文件中的标签和属性使用注解

DI分类:

set注入,设值注入构造注入

set注入,简单类型注入(简单的数据类型和String)

注入过程:按照前调用无参构造的原则,其后调用setxx方法进行赋值(和属性名无关,无关是不是类的属性),而非直接通过有参构造进行赋值

给非自定义类同理

set注入,引用类型注入


构造注入:Spring调用类中的有参构造方法,在创建对象的同时,给属性赋值


引用类型自动注入:Spring可以根据某些规则给引用类型完成赋值,只对引用类型有效,规则byName和byType

byName:按名称注入,Java类中引用类型属性名称和Spring容器中bean的id一样,且数据类型也一样,这样的bean能够赋值给引用类型。byType:按类型注入,Java类中引用类型的数据类型和Spring容器中bean的class同源关系,则可以赋值给引用类型。

byName规则

byType规则(只能有一个,具有唯一性)

同源关系

java中引用类型的数据类型和bean的class值是一样的。java中引用类型的数据类型(父)和bean的class(子)值是父子类关系的。java中引用类型的数据类型和bean的class值是接口和实现类关系的。


多个配置文件:在实际应用里,随着应用规模的增加,系统中Bean数量也大量增加口,导致配置文件变得非常庞大、臃肿。为了避免这种情况的产生,提高配置文件的可读性与可维护性,可以将Spring配置文件分解成多个配置文件。

按功能模块分,-个模块一个配置文件。按类的功能分,数据库操作相关的类在一个文件,配置redis, 事务等等的一个配置文件。

Spring管理多个配置文件:常用的是包含关系的配置文件,项目中有一个总的文件,里面是有import标签包含其他的配置文件

使用通配符*

基于注解的DI

概念:使用Spring提供的注解,完成Java对象创建,属性赋值

Component:需要在类上使用注解@Component,该注解的value属性用于指定该bean的id值

@Component(value="myTest") class Test {// do something }

利@Component功能相同的创建对象的注解。

@Repository:放在dao接口的实现类上面,表示创建dao对象,持久层对象,能访问数据库@Service:放在业务层接口的实现类上面,表示创建业务层对象,业务层对象有事务的功能@Controller:放在控制器类的上面,表示创建控制器对象。属于表示层对象。控制器对象能接受请求,把请求的处理结果显示给用户。

以上四个注解都能创建对象,但是@Repository @Service @Controller有角色说明,表示对象是分层的。对象是属于不能层的,具有额外的功能。


扫描多个包的三种方式


注解指定属性值的方式

简单类型value引用类型


简单类型value

放置位置:

在属性定义的上面,无需set方法,推荐使用在set方法的上面

@Component(value = "MyStudent")public class Student { @Value(value = "lh") private String name; @Value(value = "12") private int age; // do something}

value通过外部配置属性文件获得

// .xml

// Student.java@Component(value = "MyStudent")public class Student { // @Value("${key}") @Value("${myname}") private String name; @Value("${myage}") private int age;// do something}

# myconf.propertiesmyname=lhmyage=23

// app.javapackage com.bjpowernode;import com.bjpowernode.ba01.Student;import org.junit.Test;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class MyTest { @Test public void Test() { String config = "applicationContext.xml"; ApplicationContext ctx = new ClassPathXmlApplicationContext(config); Student st = (Student) ctx.getBean("MyStudent"); System.out.println(st); }}


引用类型

放置位置:

在属性定义的上面,无需set方法,推荐使用在set方法的上面

@Component(value = "MyStudent")public class Student { @Value("${myname}") private String name; @Value("${myage}") private int age; @Autowired() private School sl; // 提示:school必须在student赋值前先赋值}

使用byName方法(唯一性)

// School.java@Component("MySchool")public class School { @Override public String toString() { return "School{" + "name='" + name + ''' + ", age=" + age + '}'; } @Value("${lname}") private String name; @Value("${lage}") private int age;}// Student.java@Component(value = "MyStudent")public class Student {// 此处与Qualifier一起用 @Autowired @Qualifier(value = "MySchool") private School sl;}

Autowired(required): required默认是true

true: spring在启动的时候,创建容器对象时候,会检查引用类型是否赋值成功,如果赋值失败,终止程序执行, 并报错。

false:引用类型赋值失败,程序正常执行,不报错。引用类型的值是null。

另一种引用注解的方式:@Resource,为JDK提供,此处不作讲解。

AOP面向切面编程 AOP的概念

概念:AOP,Aspect Orient Programming,面向切面编程。

Aspect:表示切面,给业务方法增加的功能,叫做切面,一般是非业务功能,可复用,例如日志功能,事务功能,权限检查,参数检查,统计检查。Orient:面向,对着Programming:编程 AOP的作用

让切面编程复用

让开发人员专注业务逻辑,提高开发效率

实现业务功能和其他业务功能解耦合

给存在的业务方法,增加功能,不用修改原来的代码

AOP的术语

Aspect:表示切面,给业务方法增加的功能JoinPoint:连接点,连接切面的业务方法,在这个业务方法执行时,会同时执行切面的功能PointCut:切入点,是一个或多个连接点集合,表示这些方法执行时,都能增加切面的功能target:目标对象,给那个对象增加切面的功能,这个对象就是目标对象Advice:通知(增强),表示切面执行时间,在目标方法之前执行切面,还是目标方法之后执行切面

AOP三个最主要的要素:Aspect,PointCut,Advice,这个概念是在Advice时间,在PointCut的位置,执行Aspect。

AOP是一个动态的思想,在程序运行期间,创建代理(ServiceProxy),使用代理执行方法时,增加切面的功能,这个代理对象是存在内存中的。

AOP技术思想的实现

使用框架实现AOP,框架有很多,著名的有两个

Spring:Spring框架实现AOP思想中的部分功能。Spring框架实现AOP的操作比较繁琐、比重。Apsectj:独立的框架,专门是AOP,属于Eclipse。

Apsectj官网:

Apsectj

Apsectj可以通过xml和注解两种方式实现AOP

通知:Advice

@Before:前置通知@AfterReturnning:后置通知,在目标方法结束后触发@Around:环绕通知@AfterThrowing:异常通知@After:最终通知

位置:PointCut

表达式:execution(方法的定义)

execution(访问权限类型(可省略) 返回值类型 包名类名.方法名(参数类型和参数个数) 抛出异常类型(可省略))

可使用通配符

符号意义*0至多个任意字符··用在方法参数中,表示任意多个参数;用在包名后,表示当前包及其子包路径+用在类名后,表示当前类及其子类;用在接口后,表示当前接口及其实现类

举例

// 切面类package com.bjpowernode.handle;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Before;import org.springframework.stereotype.Component;import java.util.Date;@Aspectpublic class MyAspect { @Before(value = "execution(" + "public " + "void " + "com.bjpowernode.service.impl.SomeServiceImpl.doSome(String, Integer))") public void myBefore() { System.out.println("time" + new Date()); }}

// 接口package com.bjpowernode.service;public interface SomeService { void doSome(String name, Integer age);}// 实现类package com.bjpowernode.service.impl;import com.bjpowernode.service.SomeService;import org.springframework.stereotype.Component;public class SomeServiceImpl implements SomeService { @Override public void doSome(String name, Integer age) { System.out.println("do somehtin"); }}

<?xml version="1.0" encoding="UTF-8"?>

// 主函数package com.bjpowernode;import com.bjpowernode.service.SomeService;import com.bjpowernode.service.impl.SomeServiceImpl;import org.junit.Test;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class MyTest { @Test public void Test() { String config = "applicationContext.xml"; ApplicationContext ctx = new ClassPathXmlApplicationContext(config); SomeService service = (SomeService) ctx.getBean("myStudent"); service.doSome("lh", 20); }}

# 结果输出timeSun Feb 06 19:25:54 CST 2022# Before前置切面,完成do somehtin

此时xml会创建三个对象,一个是实现类对象,一个是切面类对象,一个是代理切面类对象

# 实现类对象myStudent# 切面类对象MyAspect# 代理切面类对象org.springframework.aop.config.internalAutoProxyCreator


获取执行切面方法的方法的信息

@Aspectpublic class MyAspect { @AfterReturning(value = "execution(" + "public " + "void " + "com.bjpowernode.service.impl.SomeServiceImpl*.doSome(String, Integer))") public void myBefore(JoinPoint js) { System.out.println(js.getSignature()); System.out.println("time" + new Date()); }}

JoinPoint不管之后加什么参数,该参数都放在第一个位置

其他此类和接口方法可自行看源码


@AfterReturnning:此方法比较特殊,因为是在方法执行之后执行,所以其可以获取方法的返回结果retunning=自定义的变量,表示目标方法的返回值的,自定义变量名称必须和通知方法的形参名一-样

@AfterReturnning(value = "", returning="res")public void mytest(Object res) { // }

环绕通知:@Around。其他通知是相当于一个配件,该通知相当于一个容器,内部包含方法执行

//环绕置通知方法的定义//1)方法是public//2)方法是必须有返回值,推荐使用object类型//3)方法名称自定义//4)方法必须有ProceedingJoinPoint参数,是用来执行方法的@Aspectpublic class MyAspect { @Around(value = "" + "execution(public void com.bjpowernode.service.impl.SomeServiceImpl2.doSome(..))") public Object fd(ProceedingJoinPoint pp) throws Throwable { // 执行目标方法 Object rr = null; rr = pp.proceed(); return rr; }}


辅助注解:@Pointcut

@Pointcut("execution(public void com.bjpowernode.service.impl.SomeServiceImpl2.doSome(..))")public void my() { // 此时代表execution中的内容 // 无需代码}@After(value = "my()") // 即可publid void my() { // do something}


Spring集成MyBatis

后面补上

Spring事务 Spring的事务概念

什么是事务?事务是一些sql序列的集合, 是多条sq|,作为一个整体执行。

什么情况下需要事务?

一个操作需要多条(2条或2条以上的sql),sql语句-起完成,操作才能成功。

事务:加在业务类的方法上面(public方法 上面),表示业务方法执行时,需要事务的支持。

不同的数据库访问技术,处理事务是不同的

JDBC访问数据库,事务处理

public void updateAccount() { conn.setAutoCommit(false); conn.setAutoCommit(true);}

MyBatis执行数据库,事务处理

public void updateAccount() { SqlSession session = SqlSession.openSession(false); try { session.commit(); } catch { session.rollback(); }}

spring统一管理事务,把不同的数据库访问技术的事务处理统一起来。

Spring事务管理器

Spring框架使用事务管理器对象,管理所有的事务。

事务管理器接口:PlatformTransactionManager,作用:定义了事务的操作,主要是commit()和rollback()

事务管理器实现类:一种数据库的访问技术有一个实现类,由具体的实现类具体完成事务的提交和回滚。

JDBC和MyBatis访问数据库有自己的事务管理器实现类:DataSourceTransactionManager。hibernate框架,他的事务管理器实现类:HibernateTransactionManager。

事务使用的是AOP的环绕通知@Around

Spring的事务定义

事务定义接口TransactionDefinition中定义了事务描述相关的三类常量:事务隔离级别、事务传播行为、事务默认超时时限,及对他们的操作。

隔离级别:控制事务之间影响的程度

ISOLATION_DEFAULT:采用DB默认的事务隔离级别,MySQL默认是ISOLATION_REPEATABLE_READ,Oracle默认是ISOLATION_READ_COMMITTED。

ISOLATION_READ_COMMITTED:读已提交,解决脏读,存在不可重复读和幻读

ISOLATION_READ_UNCOMMITTED:读未提交,未解决任何并发问题

ISOLATION_REPEATABLE_READ:可重复读解决脏读和不可重复读,存在幻读

ISOLATION_SERIALIZABLE:串行化,不存在并发问题

事务超时:表示一个业务方法最长的执行时间,没有到达时间没有执行完毕,spring回滚事务 。

以秒为单位,整数值,默认是-1。

传播行为:业务方法在调用时事务在方法之间的传递和使用,使用传播行为可以标识是否有事务。

PROPAGATION_REQUIRED:Spring默认传播行为,方法在调用时,如果存在事务,则使用当前事务;如果没有事务,则新建事务,方法在新事务中执行

PROPAGATION_REQUIRES_NEW:方法需要一个新事务,如果调用方法时,存在一个事务,则原来的事务暂停,直到新事务执行完毕;如果方法调用时没有事务,则新建一个事务,在新事务中执行代码

PROPAGATION_SUPPORTS:支持,有事务则可以正常执行,没有事务也可以正常执行,一般是查询操作。

PROPAGATION_MANDATORY

PROPAGATION_NESTED

PROPAGATION_NEVER

PROPAGATION_NOT_SUPPORTED

Spring注解管理事务 AspectJ的AOP配置事务管理

Copyright © 2016-2020 www.365daan.com All Rights Reserved. 365答案网 版权所有 备案号:

部分内容来自互联网,版权归原作者所有,如有冒犯请联系我们,我们将在三个工作时内妥善处理。