Spring 框架的使用2


在这里插入图片描述

  通知类。
  代码结构。
在这里插入图片描述


// pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>text1</artifactId>
    <version>1.0-SNAPSHOT</version>


    <dependencies>
        <!-- Spring常用依赖 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.1.6.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>5.1.6.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.12</version>
        </dependency>
        <!-- Junit -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
    </dependencies>

</project>


// User.java
@Data
public class User {
}

// IUserDao.java
public interface IUserDao {

    void show();
    int addUser(User user);
    int updateUser(User user);
    int delUser(Integer id);

}

// UserDaoImpl.java
public class UserDaoImpl implements IUserDao {


    @Override
    public void show() {
        System.out.println("show");
    }

    @Override
    public int addUser(User user) {

//        int i = 10/0;

        System.out.println("addUser\n");
        return 0;
    }

    @Override
    public int updateUser(User user) {
        System.out.println("updateUser");
        return 0;
    }

    @Override
    public int delUser(Integer id) {
        System.out.println("delUser");
        return 0;
    }
}

// IUserService.java

public interface IUserService {

    void show();
    int addUser(User user);
    int updateUser(User user);
    int delUser(Integer id);

}


// UserServiceImpl.java
@Data
public class UserServiceImpl implements IUserService {

    private IUserDao userDao;

    @Override
    public void show() {
        userDao.show();
    }

    @Override
    public int addUser(User user) {
        return userDao.addUser(user);
    }

    @Override
    public int updateUser(User user) {
        return userDao.updateUser(user);
    }

    @Override
    public int delUser(Integer id) {
        return userDao.delUser(id);
    }
}



// MyBefore.java

public class MyBefore implements MethodBeforeAdvice {

    @Override
    public void before(Method method, Object[] objects, Object o) throws Throwable {
        System.out.println("方法名:" + method.getName());
        System.out.println("参数:" + Arrays.toString(objects));
        System.out.println("目标名:" + o.getClass().getSimpleName());
        System.out.println("前置增强\n");
    }
}


// MyAfter.java

public class MyAfter implements AfterReturningAdvice {
    @Override
    public void afterReturning(Object o, Method method, Object[] objects, Object o1) throws Throwable {
        System.out.println("方法返回值: "+o);
        System.out.println("方法名: "+ method.getName());
        System.out.println("参数: "+ Arrays.toString(objects));
        System.out.println("目标名: "+ o1.getClass().getSimpleName());
        System.out.println("后置增强\n");
    }
}


// MyInterceptor.java

public class MyInterceptor implements MethodInterceptor {
    @Override
    public Object invoke(MethodInvocation methodInvocation) throws Throwable {

        System.out.println("环绕增强前\n");
        // 核心方法  放行
        Object proceed = methodInvocation.proceed();

        System.out.println("环绕增强后\n");

        return proceed;
    }
}



// MyException.java

// 异常通知
public class MyException implements ThrowsAdvice {

    public void afterThrowing(Exception ex) {
        System.out.println("出错啦..");
    }

}


// application.xml

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

    <bean id="userDao" class="com.baidu.day.text.dao.impl.UserDaoImpl"></bean>
    <bean id="userService" class="com.baidu.day.text.service.impl.UserServiceImpl">
        <property name="userDao" ref="userDao"></property>
    </bean>


<!--   aop 配置增强类 -->
    <bean id="myBefore" class="com.baidu.day.text.advice.MyBefore"></bean>
    <bean id="myAfter" class="com.baidu.day.text.advice.MyAfter"></bean>
    <bean id="myException" class="com.baidu.day.text.advice.MyException"></bean>
    <bean id="myInterception" class="com.baidu.day.text.advice.MyInterceptor"></bean>

    <aop:config>
    
        <aop:pointcut id="myBeforePointCut" expression="execution(* com.baidu.day.text.service.IUserService.addUser(..))"/>
        <aop:pointcut id="myAfterPointCut" expression="execution(* com.baidu.day.text.service.impl.UserServiceImpl.addUser(..))"/>

        <aop:advisor advice-ref="myException" pointcut="execution(* com.baidu.day.text.service.impl.UserServiceImpl.addUser(..))"></aop:advisor>
        <aop:advisor advice-ref="myInterception" pointcut="execution(* com.baidu.day.text.service.impl.UserServiceImpl.addUser(..))"></aop:advisor>

        <aop:advisor advice-ref="myBefore" pointcut-ref="myBeforePointCut"></aop:advisor>
        <aop:advisor advice-ref="myAfter" pointcut-ref="myAfterPointCut"></aop:advisor>
        
    </aop:config>

</beans>

  匹配通配切入点。


    匹配固定包名方法名
    execution(* com.baidu.day.text.service.impl.UserServiceImpl.addUser(..))

    匹配固定返回类
    execution(com.baidu.day.text.entity.User *(..))

    匹配固定参数
    execution(* *(com.baidu.day.text.entity.User))

    匹配包名、子包名
    execution(* com.baidu.day.text.service..*.*(..))

    匹配包名
    execution(* com.baidu.day.text.service.*.*(..))



// 测试

@Test
    public void addUser() {

        ApplicationContext ac = new ClassPathXmlApplicationContext("application.xml");
        IUserService userService = (IUserService) ac.getBean("userService");
        userService.addUser(null);
    }

// 打印

环绕增强前

方法名:addUser
参数:[null]
目标名:UserServiceImpl
前置增强

addUser

方法返回值: 0
方法名: addUser
参数: [null]
目标名: UserServiceImpl
后置增强

环绕增强后

  Spring + MyBatis。
  代码结构。
在这里插入图片描述


// pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>text2</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <spring.version>5.1.10.RELEASE</spring.version>
    </properties>

    <dependencies>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.3</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>2.0.3</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.21</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
            <version>5.1.47</version>
        </dependency>
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper</artifactId>
            <version>5.1.8</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.12</version>
        </dependency>
        <!-- jackjar jackson jar版本要和webMVC的版本一一对应 -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.10.2</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.9.5</version>
        </dependency>
        <dependency>
            <groupId>quartz</groupId>
            <artifactId>quartz</artifactId>
            <version>1.5.1</version>
        </dependency>
        <!-- Junit -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>

    </dependencies>
    <build>
<!--     生成 war 的包名设置   -->
<!--        <finalName>xx.xx</finalName>-->

        <resources>
<!--          可关联的资源文件  -->
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.xml</include>
                </includes>
            </resource>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.*</include>
                </includes>
            </resource>
        </resources>

    </build>

</project>


// jdbc.properties

jdbc.username=root
jdbc.password=Liu01234
jdbc.url=jdbc:mysql://localhost:3306/mydb1?characterEncoding=utf-8
jdbc.driver=com.mysql.jdbc.Driver

#<!-- 配置监控统计拦截的filters,去掉后监控界面sql无法统计-->
filters=stat 
#<!-- 配置初始化大小 -->
initialSize=6
#<!-- 配置初始化最大连接数 -->
maxActive=20
#<!-- 配置初始化最小连接数 -->
minIdle=3
#<!-- 配置获取连接等待超时的时间,1分钟单位毫秒 -->
maxWait=60000
#<!-- 检测连接是否有效的SQL -->
validationQuery=SELECT ‘x‘
#<!-- 申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效 -->
testWhileIdle=true 
#<!-- 申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能 -->
testOnBorrow=false 
#<!-- 归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能 -->
testOnReturn=false 
#<!-- 启用PSCache,必须配置大于0,当大于0时,poolPreparedStatements自动触发修改为true -->
maxPoolPreparedStatementPerConnectionSize=20 
#<!-- 对于长时间不使用的连接强制关闭 -->
removeAbandoned=true 
#<!-- 超过30秒的空闲连接就可以被关闭了,单位是秒 -->
removeAbandonedTimeout=30 
#<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
timeBetweenEvictionRunsMillis=10000 
#<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
minEvictableIdleTimeMillis=30000 


// Emp.java
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Emp implements Serializable {

    private Integer empno;
    private String ename;
    private String job;
    private Integer mgr;
    private Date hiredate;
    private Double sal;
    private double comm;
    private Integer deptno;

}

// IEmpMapper.java
public interface IEmpMapper {

    List<Emp> getAll();

    int addEmp(Emp e);

}

// IEmpService.java
public interface IEmpService {

    List<Emp> getAll();

    int addEmp(Emp e);
}

// EmpServiceImpl.java
@Data
public class EmpServiceImpl implements IEmpService {

    private IEmpMapper empMapper;

    @Override
    public List<Emp> getAll() {
        return empMapper.getAll();
    }

    @Override
    public int addEmp(Emp e) {

        int tag = empMapper.addEmp(e);

        // 运行时异常
        int i = 10/0;

        return tag;
    }
}



// EmpMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >

<mapper namespace="com.baidu.day.text.dao.IEmpMapper">

    <insert id="addEmp" parameterType="emp">
        insert into emp(ename, job, mgr, sal, hiredate, comm, deptno)
        values(#{ename},#{job},#{mgr},#{sal},#{hiredate},#{comm},#{deptno})
    </insert>
    <select id="getAll" resultType="emp">
        select * from emp
    </select>

</mapper>


// spring.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       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
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd
">

<!--    数据库 -->
    <context:property-placeholder location="classpath*:jdbc.properties" />
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${jdbc.driver}" />
        <property name="url" value="${jdbc.url}" />
        <property name="username" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />
    </bean>

    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
<!--       别名 -->
        <property name="typeAliasesPackage" value="com.baidu.day.text.entity" />
<!--        <property name="mapperLocations">-->
<!--            <array>-->
<!--                <value>classpath*:com/baidu/day/text/mapper/*.xml</value>-->
<!--            </array>-->
<!--        </property>-->
<!--        读取 mapper.xml 文件 -->
        <property name="mapperLocations" value="classpath*:com/baidu/day/text/mapper/*.xml" />
    </bean>

    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!--       mapper 接口包位置 bean name 首字母小写, IEmpMapper, i开头好像不用小写 -->
        <property name="basePackage" value="com.baidu.day.text.dao" />
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
    </bean>
    <bean id="empService" class="com.baidu.day.text.service.impl.EmpServiceImpl">
        <property name="empMapper" ref="IEmpMapper" />
    </bean>

<!--  事务  -->
<!--  配置事务管理  -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>

<!--   事务声明 -->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
<!--     timeout 超时时间;rollback-for,碰到什么样的报错回滚;propagation,事务隔离级别;       -->
<!--        <tx:method name="addEmp" propagation="REQUIRED"  rollback-for="Exception" timeout="60"/>-->

            <tx:method name="show*" read-only="true" propagation="SUPPORTS"/>
            <tx:method name="get*" read-only="true" propagation="SUPPORTS"/>
            <tx:method name="select*" read-only="true" propagation="SUPPORTS"/>
            <tx:method name="add*" propagation="REQUIRED" rollback-for="Exception"  />
            <tx:method name="update*" propagation="REQUIRED" rollback-for="Exception"  />
            <tx:method name="del*" propagation="REQUIRED" rollback-for="Exception"  />
            <tx:method name="delete*" propagation="REQUIRED" rollback-for="Exception"  />
            <tx:method name="insert*" propagation="REQUIRED" rollback-for="Exception"  />
<!--            <tx:method name="*" propagation="REQUIRED" rollback-for="Exception"  />-->

        </tx:attributes>
    </tx:advice>

<!--   事务部署 -->
    <aop:config>
        <aop:advisor advice-ref="txAdvice" pointcut="execution(* com.baidu.day.text.service..*.*(..))"></aop:advisor>
    </aop:config>

</beans>


// 测试

	@Test
    public void getAll() {

        ApplicationContext ac = new ClassPathXmlApplicationContext("application.xml");
        IEmpService empService = (IEmpService)ac.getBean("empService");
        List<Emp> all = empService.getAll();
        for (Emp emp : all) {
            System.out.println(emp);
        }
    }

    @Test
    public void addEmp() {

        ApplicationContext ac = new ClassPathXmlApplicationContext("application.xml");
        IEmpService empService = (IEmpService)ac.getBean("empService");
        Emp emp = new Emp();
        emp.setEname("张三");
        emp.setJob("程序员");
        emp.setHiredate(new Date());
        emp.setDeptno(10);
        emp.setComm(33.0);
        emp.setMgr(1);
        emp.setSal(22.0);
        int i = empService.addEmp(emp);
        System.out.println(i);
    }

  <tx:method,事务属性。
  isolation,隔离级别。级别越高,多事务并发时,越安全,并发越差。
  default,采用数据库的默认的设置。
  read-uncommited,读未提交。
  read-commited,读提交,Oracle数据库默认的隔离级别。
  repeatable-read,可重复读,MySQL 数据库默认的隔离级别。
  serialized-read,序列化读,级别最高。

  事务并发时的安全问题。
  脏读,一个事务读取到另一个事务还未提交的数据,大于等于 read-commited 可防止。
  不可重复读,一个事务内多次读取一行数据的相同内容,其结果不一致,大于等于 repeatable-read 可防止。
  幻影读,一个事务内多次读取一张表中的相同内容,其结果不一致,serialized-read 可防止。

  propagation,传播行为。
  当涉及到事务嵌套(Service调用Service)时,可以设置。
  SUPPORTS,不存在外部事务,则不开启新事务;存在外部事务,则合并到外部事务中。适合查询。
  REQUIRED,不存在外部事务,则开启新事务;存在外部事务,则合并到外部事务中。 默认值,适合增删改。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值