Spring[02.基础知识整理(下)]

发布时间:2020-08-09 23:28:40 作者:IMUKL8
来源:网络 阅读:993

Bean使用外部属性文件

Spel表达式

是一个支持运行时查询和操作对象图的强大的表达式语言

通过 SpEL 可以实现:

案例

验证邮箱

^[_A-Za-z0-9-]+(\.[_A-Za-z0-9-]+)"+"*@[A-Za-z0-9]+(\.[A-Za-z0-9]+)*(\.[A-Za-z]{2,})$

Bean的生命周期

生命周期

Bean后置处理器

基本介绍

在初始化方法被调用前后, Spring 将把每个 Bean 实例分别传递给上述接口的以下两个方法:

public class MyBeanPostProcesser implements BeanPostProcessor {

    // 在init-method之前调用
    @Override
    public Object postProcessBeforeInitialization(Object o, String s) throws BeansException {
        System.out.println("postProcessBeforeInitialization:  " + s);
        return o;
    }

    // 在init-method之后调用
    @Override
    public Object postProcessAfterInitialization(Object o, String s) throws BeansException {
        System.out.println("postProcessAfterInitialization:  " + s);
        return o;
    }
}
后置处理器特性

//Bean 后置处理器允许在调用初始化方法前后对 Bean 进行额外的处理.
//Bean 后置处理器对 IOC 容器里的所有 Bean 实例逐一处理, 而非单一实例.
// 其典型应用是: 检查 Bean 属性的正确性或根据特定的标准更改 Bean 的属性.

//采用前置和后置处理之后
//首先运行构造函数
//然后给属性赋值
//然后访问前置处理函数
//然后访问init函数
//然后访问后置处理函数
//然后输出结果
//最后访问destroy函数

@Autowired 自动装配 Bean

AOP与AspectJ

概述

是一种新的方法论, 是对传统 OOP(Object-Oriented Programming, 面向对象编程) 的补充.

AOP 的主要编程对象是切面(aspect), 而切面模块化横切关注点.

在应用 AOP 编程时, 仍然需要定义公共功能, 但可以明确的定义这个功能在哪里, 以什么方式应用, 并且不必修改受影响的类. 这样一来横切关注点就被模块化到特殊的对象(切面)里.

AOP 的好处:

术语

AspectJ

AspectJ:Java 社区里最完整最流行的 AOP 框架.在 Spring2.0 以上版本中, 可以使用基于 AspectJ 注解或基于 XML 配置的 AOP

依赖包:

AspectJ通知注解

案例

@Aspect
@Order(0)
public class AspectProcessor {

    // 合并切入点
    @Pointcut("execution(* com.demo.aop.aspect.CalculatorImpl.*(..)))")
    public void combinePointCut(){}

    // 此函数在指定的bean方法执行前响应
    // @Before("execution (* com.demo.aop.aspect.CalculatorImpl.*(..))")
    @Before("combinePointCut()")
    public void beforeAspectProcessor(JoinPoint joinPoint){
        System.out.println("beforeAspectProcessor method name: " + joinPoint.getSignature().getName());
        System.out.println("beforeAspectProcessor method args: " + Arrays.asList(joinPoint.getArgs()));
    }

    // 此函数在指定的bean方法执行后响应
    // @After("execution (* com.demo.aop.aspect.CalculatorImpl.*(..))")
    @After("combinePointCut()")
    public void afterAspectProcessor(JoinPoint joinPoint){
        System.out.println("afterAspectProcessor method name: " + joinPoint.getSignature().getName());
        System.out.println("afterAspectProcessor method args: " + Arrays.asList(joinPoint.getArgs()));
    }

//    此函数在指定的bean方法执行前、后响应
//    @Around("combinePointCut()")
//    public void around(ProceedingJoinPoint pjp) throws Throwable{
//        System.out.println("已经记录下操作日志@Around 方法执行前");
//        pjp.proceed();
//        System.out.println("已经记录下操作日志@Around 方法执行后");
//    }

    // 如果只想在连接点返回的时候记录, 应使用返回通知代替后置通知
    @AfterReturning(value = "combinePointCut()", returning = "result")
    public void afterReturningAspectProcessor(JoinPoint joinPoint, Object result){
        System.out.println("afterReturningAspectProcessor method name: " + joinPoint.getSignature().getName());
        System.out.println("afterReturningAspectProcessor method args: " + Arrays.asList(joinPoint.getArgs()));
        System.out.println("afterReturningAspectProcessor method result: " + result);

    }

    // 异常通知
    @AfterThrowing(value = "combinePointCut()", throwing = "e")
    public void afterThrowingAspectProcessor(JoinPoint joinPoint, Exception e){
        System.out.println("afterThrowingAspectProcessor method name: " + joinPoint.getSignature().getName());
        System.out.println("afterThrowingAspectProcessor method args: " + Arrays.asList(joinPoint.getArgs()));
        System.out.println("afterThrowingAspectProcessor method throwing: " + e);
    }
}

<!--让aspectj @before @after注解生效-->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
<context:component-scan base-package="com.demo.aop.aspect"></context:component-scan>

通过代理方式实现AspectJ

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;

/**
 * Created by plusplusxu on 2017/10/23.
 *
 * 动态代理模式主要用来做方法的增强,让你可以在不修改源码的情况下,增强一些方法,
 * 在方法执行前后做任何你想做的事情(甚至根本不去执行这个方法),
 * 因为在InvocationHandler的invoke方法中,你可以直接获取正在调用方法对应的Method对象,
 * 具体应用的话,比如可以添加调用日志,做事务控制等。
 * 动态代理是设计模式当中代理模式的一种。
 */
@Repository
public class CalculatorImplProxy {

    @Autowired
    private Calculator target;

    public Calculator getProxy(){
        Calculator proxy = null;

        // 代理对象由哪一个加载器加载
        ClassLoader loader = target.getClass().getClassLoader();

        // 代理对象的内容
        Class[] interfaces = new Class[]{Calculator.class};

        // 当调用代理对象的方法的时候,该方法被执行
        InvocationHandler h = new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

                // 代理对象方法执行前操作
                System.out.println("method: " + method.getName() + "  " + "  args:  " + Arrays.asList(args));

                Object result = method.invoke(target, args);

                // 代理对象方法执行后操作
                System.out.println("method: " + method.getName() + "  " + "  args:  " + Arrays.asList(args) + "  result: " + result);

                return result;
            }
        };

        proxy = (Calculator)Proxy.newProxyInstance(loader, interfaces, h);

        return proxy;
    }
}

JDBC

JdbcTemplate

作为 Spring JDBC 框架的核心, JDBC 模板的设计目的是为不同类型的 JDBC 操作提供模板方法. 每个模板方法都能控制整个过程, 并允许覆盖过程中的特定任务. 通过这种方式, 可以在尽可能保留灵活性的情况下, 将数据库存取的工作量降到最低.

JdbcDaoSupport

该类声明了 jdbcTemplate 属性, 它可以从 IOC 容器中注入, 或者自动从数据源中创建.

package com.mysql;

import org.springframework.jdbc.core.BatchPreparedStatementSetter;
import org.springframework.jdbc.core.JdbcTemplate;

import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.List;

/**
 * Created by plusplusxu on 2017/10/25.
 *
 * 操作mysql的数据类
 *
 * JdbcTemplate 类被设计成为线程安全的, 所以可以再 IOC 容器中声明它的单个实例, 并将这个实例注入到所有的 DAO 实例中.
 */
public class ProjectDao {

    public ProjectDao(JdbcTemplate jdbcTemplateObject) {
        this.jdbcTemplateObject = jdbcTemplateObject;
    }

    public ProjectDao() {
    }

    public JdbcTemplate getJdbcTemplateObject() {
        return jdbcTemplateObject;
    }

    public void setJdbcTemplateObject(JdbcTemplate jdbcTemplateObject) {
        this.jdbcTemplateObject = jdbcTemplateObject;
    }

    // spring 提供的访问数据库的工具类,需要配置javax.sql.DataSource
    // 本例中在applicationContext中配置的mysql数据源
    private JdbcTemplate jdbcTemplateObject;

    // 添加一条项目记录
    // tbl_devops_project为vsdo数据库的项目表(Project)
    public void addproject(Project project) {
        String sql = "INSERT INTO tbl_devops_project(name,public,language,description," +
                "admin, members, gitlab_id,gitlab_url,code_styles,sonar_lint_server_url) " +
                "VALUES(?,?,?,?,?,?,?,?,?,?)";

        try {
            jdbcTemplateObject.update(sql, project.getName(),project.getPub(),project.getLanguage(),project.getDescription(),
                    project.getAdmin(),project.getMembers(),project.getGitlab_id(),
                    project.getGitlab_url(),project.getCode_styles(),project.getSonar_lint_server_url());
        }
        catch (Exception e){
            System.out.println(e);
        }

        return ;
    }

    // 根据项目名删除记录
    public void delprojectbyname(String name) {
        String sql = "DELETE FROM tbl_devops_project WHERE name=?";

        try {
            jdbcTemplateObject.update(sql,name);
        }
        catch (Exception e){
            System.out.println(e);
        }

        return ;
    }

    // 删除所有项目
    public void delallproject() {
        String sql = "DELETE FROM tbl_devops_project";
        try {
            jdbcTemplateObject.update(sql);
        }
        catch (Exception e){
            System.out.println(e);
        }

        return ;
    }

    // 更新某个项目
    public void updproject(Project project) {
        String sql = "UPDATE tbl_devops_project set description=? WHERE name=?";
        try {
            jdbcTemplateObject.update(sql,project.getDescription(), project.getName());
        }
        catch (Exception e){
            System.out.println(e);
        }

        return ;
    }

    // 获取所有项目
    public List<Project> allproject() {
        List<Project> projects = null;
        String sql = "SELECT * FROM tbl_devops_project";
        try {
            // ProjectMapper 项目表的映射类
            projects = jdbcTemplateObject.query(sql, new ProjectMapper());
        }
        catch (Exception e){
            System.out.println(e);
        }

        return projects;
    }

    // 查询项目名对应的记录
    public List<Project> queryprojectbyname(String name) {
        List<Project> projects = null;
        String sql = "SELECT * FROM tbl_devops_project WHERE name=?";
        try {
            projects = jdbcTemplateObject.query(sql, new Object[]{name}, new ProjectMapper());
        }
        catch (Exception e){
            System.out.println(e);
        }

        return projects;
    }

    // 打印所有项目
    public void displayall(){
        List<Project> projects = allproject();
        for(Project s : projects){
            System.out.println(s);
        }
    }

    // 批量插入
    public void insertBatch(final List<Project> projects){
        String sql = "INSERT INTO tbl_devops_project(name,public,language,description," +
                "admin, members, gitlab_id,gitlab_url,code_styles,sonar_lint_server_url) " +
                "VALUES(?,?,?,?,?,?,?,?,?,?)";

        jdbcTemplateObject.batchUpdate(sql, new BatchPreparedStatementSetter() {

            @Override
            public void setValues(PreparedStatement ps, int i) throws SQLException {
                Project project = projects.get(i);

                ps.setString(1, project.getName());
                ps.setBoolean(2, project.getPub());
                ps.setString(3, project.getLanguage());
                ps.setString(4, project.getDescription());
                ps.setString(5, project.getAdmin());
                ps.setString(6, project.getMembers());
                ps.setInt(7, project.getGitlab_id());
                ps.setString(8, project.getGitlab_url());
                ps.setString(9, project.getCode_styles());
                ps.setString(10, project.getSonar_lint_server_url());
            }

            @Override
            public int getBatchSize() {
                return projects.size();
            }
        });
    }
}
package com.mysql;

import org.springframework.jdbc.core.BatchPreparedStatementSetter;
import org.springframework.jdbc.core.support.JdbcDaoSupport;

import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.List;

/**
 * Created by plusplusxu on 2017/10/26.
 *
 * 继承于JdbcDaoSupport,直接封装了JdbcTemplate,写起来更方便
 *
 * 该类声明了 jdbcTemplate 属性, 它可以从 IOC 容器中注入, 或者自动从数据源中创建.
 *
 */
public class JdbcDaoSupportImpl extends JdbcDaoSupport {
    // 添加一条项目记录
    // tbl_devops_project为vsdo数据库的项目表(Project)
    public void addproject(Project project) {
        String sql = "INSERT INTO tbl_devops_project(name,public,language,description," +
                "admin, members, gitlab_id,gitlab_url,code_styles,sonar_lint_server_url) " +
                "VALUES(?,?,?,?,?,?,?,?,?,?)";

        try {
            this.getJdbcTemplate().update(sql, project.getName(),project.getPub(),project.getLanguage(),project.getDescription(),
                    project.getAdmin(),project.getMembers(),project.getGitlab_id(),
                    project.getGitlab_url(),project.getCode_styles(),project.getSonar_lint_server_url());
        }
        catch (Exception e){
            System.out.println(e);
        }

        return ;
    }

    // 根据项目名删除记录
    public void delprojectbyname(String name) {
        String sql = "DELETE FROM tbl_devops_project WHERE name=?";

        try {
            this.getJdbcTemplate().update(sql,name);
        }
        catch (Exception e){
            System.out.println(e);
        }

        return ;
    }

    // 删除所有项目
    public void delallproject() {
        String sql = "DELETE FROM tbl_devops_project";
        try {
            this.getJdbcTemplate().update(sql);
        }
        catch (Exception e){
            System.out.println(e);
        }

        return ;
    }

    // 更新某个项目
    public void updproject(Project project) {
        String sql = "UPDATE tbl_devops_project set description=? WHERE name=?";
        try {
            this.getJdbcTemplate().update(sql,project.getDescription(), project.getName());
        }
        catch (Exception e){
            System.out.println(e);
        }

        return ;
    }

    // 获取所有项目
    public List<Project> allproject() {
        List<Project> projects = null;
        String sql = "SELECT * FROM tbl_devops_project";
        try {
            // ProjectMapper 项目表的映射类
            projects = this.getJdbcTemplate().query(sql, new ProjectMapper());
        }
        catch (Exception e){
            System.out.println(e);
        }

        return projects;
    }

    // 查询项目名对应的记录
    public List<Project> queryprojectbyname(String name) {
        List<Project> projects = null;
        String sql = "SELECT * FROM tbl_devops_project WHERE name=?";
        try {
            projects = this.getJdbcTemplate().query(sql, new Object[]{name}, new ProjectMapper());
        }
        catch (Exception e){
            System.out.println(e);
        }

        return projects;
    }

    // 打印所有项目
    public void displayall(){
        List<Project> projects = allproject();
        for(Project s : projects){
            System.out.println(s);
        }
    }

    // 批量插入
    public void insertBatch(final List<Project> projects){
        String sql = "INSERT INTO tbl_devops_project(name,public,language,description," +
                "admin, members, gitlab_id,gitlab_url,code_styles,sonar_lint_server_url) " +
                "VALUES(?,?,?,?,?,?,?,?,?,?)";

        this.getJdbcTemplate().batchUpdate(sql, new BatchPreparedStatementSetter() {

            @Override
            public void setValues(PreparedStatement ps, int i) throws SQLException {
                Project project = projects.get(i);

                ps.setString(1, project.getName());
                ps.setBoolean(2, project.getPub());
                ps.setString(3, project.getLanguage());
                ps.setString(4, project.getDescription());
                ps.setString(5, project.getAdmin());
                ps.setString(6, project.getMembers());
                ps.setInt(7, project.getGitlab_id());
                ps.setString(8, project.getGitlab_url());
                ps.setString(9, project.getCode_styles());
                ps.setString(10, project.getSonar_lint_server_url());
            }

            @Override
            public int getBatchSize() {
                return projects.size();
            }
        });
    }
}
<?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原生的DriverManagerDataSource和mysql驱动配置数据源-->
    <bean id="datasource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <!--注意一下&characterEncoding要修改为&characterEncoding-->
        <!--vsdo为mysql数据库名称-->
        <property name="url" value="jdbc:mysql://localhost:3306/vsdo?useUnicode=true&characterEncoding=utf-8"/>
        <property name="username" value="root"/>
        <property name="password" value="123456" />
    </bean>

    <!---->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <!--配置数据源依赖-->
        <property name="dataSource" ref="datasource" />
    </bean>

    <bean id="projectDaoImp" class="com.mysql.ProjectDao">
        <!--添加jdbc访问类依赖-->
        <property name="jdbcTemplateObject" ref="jdbcTemplate"></property>
    </bean>

    <bean id="jdbcDaoSupportImpl" class="com.mysql.JdbcDaoSupportImpl">
        <property name="dataSource" ref="datasource"></property>
    </bean>
</beans>

事务

事务管理是企业级应用程序开发中必不可少的技术, 用来确保数据的完整性和一致性.

事务就是一系列的动作, 它们被当做一个单独的工作单元. 这些动作要么全部完成, 要么全部不起作用

事务的四个关键属性(ACID)

Spring 既支持编程式事务管理, 也支持声明式的事务管理.

用 @Transactional 注解声明式地管理事务

Spring 还允许简单地用 @Transactional 注解来标注事务方法.

Spring[02.基础知识整理(下)]

事务的传播行为

当事务方法被另一个事务方法调用时, 必须指定事务应该如何传播. 例如: 方法可能继续在现有事务中运行, 也可能开启一个新事务, 并在自己的事务中运行.

Spring[02.基础知识整理(下)]

推荐阅读:
  1. 【星云测试】开发者测试-采用精准测试工具对Spring Boot应用进行测试
  2. 怎么在spring中解决循环依赖问题

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

spring jdbc 事务

上一篇:泛圈企业云盘推动企业信息化提高企业办公效率

下一篇:Forrester 高级分析师:全球超融合市场发展的5个重要趋势

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》