Spring(4)

1.Aop

  • 前置通知【@Before】:在目标方法执行之前执行的功能
  • 后置通知【@After】: 在目标方法执行之后,无论目标方法能否正常执行成功,后置通知都会执行
  • 返回通知【@AfterReturning】: 在目标方法执行之后,在目标方法执行成功的前提下,返回通知才执行
  • 异常通知【@AfterThrowing】:在目标方法执行之后,在目标方法出现异常的情况下,异常通知才会执行
  • 环绕通知【@Around】:以一抵四

1.1切面中的五种通知[方法]

@Component
@Aspect//这表示当前类是一个切面类
public class LogAspect {

	//前置通知
	@Before("execution(public int com.offcn.p1.service.CaculatorImpl.*(int, int))")
	public void printBeforeLog() {
		
		System.out.println("method before.........");
	}
	//后置通知
	@After("execution(public int com.offcn.p1.service.CaculatorImpl.*(int, int))")
	public void printAfterLog() {
		System.out.println("method after.........");
	}
	
	//返回通知
	@AfterReturning("execution(public int com.offcn.p1.service.CaculatorImpl.*(int, int))")
	public void printAfterReturnLog() {
		System.out.println("method afterReturning.........");
	}
	//异常通知
	@AfterThrowing("execution(public int com.offcn.p1.service.CaculatorImpl.*(int, int))")
	public void printAfterThrowingLog() {
			System.out.println("method afterThrowing.........");
	}	
}

1.2通知的底层结构

通知的底层结结构:

		try {
			try {
				//1.前置通知
				//2.目标方法
			}finally {
				//3.后置通知
			}
			   //4.返回通知
		}catch (Throwable e) {
			//5.异常通知
		}

1.3切入点表达式

作用:定位目标方法【被拓展的方法】
语法:execution([权限修饰符] [返回值类型] [简单类名/全类名] [方法名] ([参数列表]))

最复杂【最精确】:execution(public int com.offcn.p1.service.CaculatorImpl.add(int,int))
最简洁【最模糊】:execution(* *.*(..))

切入点表达式的重用:

@Pointcut("execution(* *.*(..))")
public void myPointCut() {}

//前置通知
@Before("myPointCut()")
public void printBeforeLog() {
  		System.out.println("method before.........");
}

切入点表达式支持:&& || !运算符。
在这里插入图片描述

1.4从通知中获取目标方法的信息

在这里插入图片描述 前置通知

@Before("execution(public int com.offcn.p1.service.CaculatorImpl.add(int, int)) || execution(public int com.offcn.p1.service.CaculatorImpl.substract(int, int))")
public void printBeforeLog(JoinPoint joinPoint) {
	//1.获取目标方法签名
    String name=joinPoint.getSignature().getName();
	//2.获取参数列表
	Object[] args = joinPoint.getArgs();
	List<Object> asList = Arrays.asList(args);
	System.out.println("前置通知,获取目标方法名:"+name+",传递过来的参数列表为:"+asList);
}

返回通知:

@AfterReturning(value="myPointCut()",returning="result")
public void printAfterReturnLog(Object result) {
	System.out.println("method afterReturning........."+result);
}

要求:

  1. 给@AfterReturning加一个returning属性
  2. returning属性值一定要和返回通知的参数名一致,参数类型最好为Object类型

异常通知:

@AfterThrowing(value="myPointCut()",throwing="ex")
public void printAfterThrowingLog(Throwable ex) {
		System.out.println("method afterThrowing.........,异常信息为:"+ex.getMessage());
}

要求:

  1. @AfterThrowing加一个throwing属性
  2. throwing属性值必须和异常通知的参数名一致,参数类型最好是Throwable类型
    在这里插入图片描述

1.5环绕通知实现事务切面

事务:

Connection conn=JdbcUtils.getConnection();
Try{
Conn.setAutoCommit(false);//开启事务
//调用dao层发送sql语句
Conn.commit(); //提交事务
}catch(Exception ex){
   Conn.rollback();//回滚
}finally{
  Conn.close(); //释放连接
}
@Component
@Aspect
public class TransactionAspect {
	//环绕通知		
	@Around("com.offcn.p1.service.LogAspect.myPointCut()")
	public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
		Object result = null;
		try {
			try {
				//1.执行前置通知----->获取数据库连接、Conn.setAutoCommit(false);//开启事务
				//执行目标方法
				result = joinPoint.proceed();
			}finally {
				//2.后置通知
			}
			  //3.返回通知----》 提交事务 conn.commit();
		}catch (Exception e) {
			// 4.异常通知
			e.printStackTrace(); //回滚事务conn.rollback();
		}
		return result;
	}
}

1.6多切面情况下的切面优先级问题

多切面情况下,切面的优先级是靠切面上的@Order注解决定的,value值越小,优先级越高。
如果切面类上都不加注解,切面的优先级是靠着切面类的类名。

1.7多切面情况下的各个通知优先级问题

第一种:目标方法能够正常执行
第二种:目标方法出现异常,内层切面抛出异常
第二种:目标方法出现异常,内层切面不抛出异常!

1.8基于xml的aop配置

<!-- 1.将被代理类和切面类对象放入到容器中 -->
  <bean id="caculatorImpl" class="com.offcn.p1.service.CaculatorImpl"></bean>
  <bean id="logAspect" class="com.offcn.p1.service.LogAspect"></bean>
  <bean id="transactionAspect" class="com.offcn.p1.service.TransactionAspect"></bean>
  
  <aop:config>
      <!-- 指定切入点表达式 -->
      <aop:pointcut expression="execution(public int com.offcn.p1.service.CaculatorImpl.*(..))" id="myPointCut"/>
      <!-- 指定切面 -->
      <aop:aspect ref="logAspect" order="10">
         <aop:before method="printBeforeLog" pointcut-ref="myPointCut"/>
         <aop:after method="printAfterLog" pointcut-ref="myPointCut"/>
         <aop:after-returning method="printAfterReturnLog" returning="result" pointcut-ref="myPointCut"/>
         <aop:after-throwing method="printAfterThrowingLog"  throwing="ex" pointcut-ref="myPointCut"/>
      </aop:aspect>
      <aop:aspect ref="transactionAspect" order="9">
         <aop:around method="around" pointcut-ref="myPointCut"/>
      </aop:aspect>
  </aop:config>

1.9JdbcTemplate介绍

Spring的JdbcTemplate实际上就是Spring框架对原生Jdbc的简单封装,类似于我们JavaWeb部分学过的DBUtils工具类,用来完成对数据表数据的增删改查操作。

第一步:导入jar包
在这里插入图片描述第二步:在spring的配置文件中配置JdbcTemplate
在这里插入图片描述第三步:在Dao层注入JdbcTemplate
在这里插入图片描述第四步:在Dao层方法使用JdbcTemplate对数据表进行增删改查操作

@Repository
public class EmployeeDao {
	@Autowired
	private JdbcTemplate jdbcTemplate;
	public void insert(Employee employee) {
		String sql="insert into employee(emp_name,salary) values(?,?)";
		jdbcTemplate.update(sql, employee.getEname(),employee.getSalary());
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值