栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

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

Linux 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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

目录

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的配置文件



    
	
    
  

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.properties
myname=lh
myage=23
// app.java
package 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;


@Aspect
public 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");
    }
}


    

    
    
    

// 主函数
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

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

@Aspect
public 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参数,是用来执行方法的
@Aspect
public 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配置事务管理
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/728211.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号