SpringAOP的概念以及基本使用

SpringAOP

spring AOP概念
  1. AOP的概念

    • AOP:面相切面编程思想,即将一些共性的内容进行抽取,在需要用到的地方,以动态代理的方式进行插入在不修改源码的基础上,还能对源码进行前后的增强

    • 底层实现技术:动态代理

    • AOP的应用: 权限拦截、日志的输出、性能的检测、事务管理

  2. AOP术语

    • 切面(Aspect):横切关注点被模块化的特殊对象(切点+通知/增强=切面)
    • 通知/增强(advice):切面必须要完成的工作,增强的那段代码方法
    • 目标(Target):被通知的对象
    • 代理(Proxy):向目标对象应用通知之后创建的对象
    • 连接点(Joinpoint):程序执行的某个特定位置,即可以被增强的方法
    • 切点(pointcut):每个类都拥有多个连接点,即要被增强的方法,小于等于连接点个数
    • 织入: 切入点集成到切面的这一个过程,就叫做织入过程
Spring AOP的环境搭建
  1. 导入jar包

    com.springsource.org.aopalliance-1.0.0.jar
    com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
    spring-aop-4.2.4.RELEASE.jar
    spring-aspects-4.2.4.RELEASE.jar

  2. 在配置文件中加入aop的命名空间

    <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"
        xmlns:context="http://www.springframework.org/schema/context" 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">
    
  3. 配置文件中的配置

    <!-- 配置扫描器,扫描com.edu以及其子包下的注解 -->
    <context:component-scan base-package="com.edu"/>
    <!-- 使AspectJ注解生效,自动为匹配的类生成代理对象 -->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
    
  4. 创建切面类,增强方法

    @Order(1)						//注解指定切面的优先级
    @Aspect							//声明此类是一个切面类
    @Component("userAspect")		//放入spring容器
    public class userAspect {
    
    	//声明切入点表达式,可以避免代码重入,即下面的通知可@Before("pointCut()")书写
    	@Pointcut("execution(* com.edu.user.User.*(..))")
    	public void pointCut() {
    		
    	}
    	
    	//声明该方法是一个前置通知:在目标方法开始之前执行
    	@Before("execution(* com.edu.user.User.*(..))")
        //@Before("pointCut()")		//也可以调用上面的切入点
    	public void before() {
    		System.out.println("执行方法之前!!!");
    	}
    }
    
通知类型

通知类型:

  1. @Before:前置通知 在连接点之前增强 权限拦截

  2. @After:后置通知 在连接点之后增强(无论是否出现异常) 日志输出

  3. @Around:环绕通知 在连接点之前和连接点之后都增强 性能检测

    /**
     * 	环绕通知需要携带ProceedingJoinPoint类型的参数
     * 	环绕通知类似于动态代理的全过程,ProceedingJoinPoint类型的参数可以决定是否执行目标方法,即proceed()方法
     * 	且环绕通知必须有返回值,返回值即为目标方法的返回值
     * @param joinPoint
     * @return
     */
    @Around(value = "execution(* com.edu.user.User.*(..))")
    public Object around(ProceedingJoinPoint joinPoint) {
    	Object result = null;
    	String method = joinPoint.getSignature().getName();
    
    	try {
    		//前置通知
    		System.out.println(method + "被执行了!!!");
    		//执行原方法
    		result = joinPoint.proceed();
    		//返回通知
    		System.out.println(method + "执行了!!!");
    	} catch (Throwable e) {
    		//异常通知
    		System.out.println(method + "出现异常了!!!");
    		throw new RuntimeException(e); 
    	}
    	//后置通知
    	System.out.println(method + "执行完了!!!");
    	return result;
    }
    
  4. @AfterRunning:返回通知, 在方法返回结果之后执行,可以访问到方法的返回值

    /**
     * 	返回通知, 在方法返回结果之后执行,可以访问到方法的返回值
     *  @param joinPoint
     *  @param result		//方法的返回值
     */
    @AfterReturning(value = "execution(* com.edu.user.User.*(..))",
    		returning = "result")
    public void afterReturning(JoinPoint joinPoint,Object result) {
    	//获取切点的方法名
    	String method = joinPoint.getSignature().getName();
    	System.out.println(method+"方法被执行完了!!!");
    }
    
  5. @AfterThrowing:异常通知, 在方法抛出异常之后,可以访问到方法抛出的异常

    /**
     * 	在目标方法出现异常时会执行的代码
     * 	可以访问到异常对象,且可以指定在出现特定的异常时(NullPointExecption)执行此代码
     * @param joinPoint
     * @param e
     */
    @AfterThrowing(value = "execution(* com.edu.user.User.*(..))",throwing = "e")
    public void afterThowing(JoinPoint joinPoint,Exception e) {
       	String method = joinPoint.getSignature().getName();
       	System.out.println(method + "方法出现了"+ e + "异常");
    }
    
JdbcTemplate
  1. 概念

    jdbcTemplate是spring提供的dao层用来和数据库数据交互的技术

  2. JdbcTemplate的使用方式

    1. 导包:spring-jdbc.jar、spring-tx.jar

    2. 在applicationContext.xml文档中配置

    <!-- 加载外部配置文件,jdbc.properties -->
    <context:property-placeholder location="classpath:jdbc.properties"/>
    <!-- c3p0连接池提供给JdbcTemplate一个数据库连接 -->
    <bean id="c3p0" class="com.mchange.v2.c3p0.ComboPooledDataSource">
    	<property name="driverClass" value="${jdbc.driver}"></property>
    	<property name="jdbcUrl" value="${jdbc.url}"></property>
    	<property name="user" value="${jdbc.userName}"></property>
    	<property name="password" value="${jdbc.passWord}"></property>
    </bean>
    <!-- jdbcTemplate -->
    <bean id="JdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
    	<property name="dataSource" ref="c3p0"></property>
    </bean>
    
    1. 使用JdbcTemplate实现增删改查
    public class UserDaoImp implements UserDao {
    	private JdbcTemplate jdbcTemplate;
    	public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
    		this.jdbcTemplate = jdbcTemplate;
    	}
        //增删改与QueryRunner类似
    	public void save() {	
    		String sql = "insert into user values(?,?)";
    		jdbcTemplate.update(sql, "zhangshan",20);
    		
    	}
        //全查使用BeanPropertyRowMapper()
    	public void findAll() {
    		String sql = "select * from user";
    		List<User> list = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(User.class));
    		for (User user : list) {
    			System.out.println(user);
    		}
    		
    	}
        //查询单个
    	public void findByUserName() {
    		String sql = "select * from user where username = ?";
    		User user = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<>(User.class),"李四");
    		System.out.println(user);
    	}
        //聚合查
    	public void findCount() {
    		String sql = "select count(*) from user";
    		Long count = jdbcTemplate.queryForObject(sql, long.class);
    		System.out.println(count);
    	}
    }
    
    
JdbcTemplate 在dao层的两种注入方式
  1. set方式注入,能够使用注解
  2. 基继承方式让jdbctemplate继承JdbcDaoSupport 不能使用注解,applicationContext.xml需要用set方式配置,继承的父类中有jdbctemplate,可以使用getJdbcTemplate()获取父类的jdbctemplate对象
spring 事务的全xml配置方式
<!-- 加载外部配置文件,jdbc.properties -->
<context:property-placeholder location="classpath:jdbc.properties" />
<!-- c3p0连接池提供给JdbcTemplate -->
<bean id="c3p0" class="com.mchange.v2.c3p0.ComboPooledDataSource">
	<property name="driverClass" value="${jdbc.driver}"></property>
	<property name="jdbcUrl" value="${jdbc.url}"></property>
	<property name="user" value="${jdbc.userName}"></property>
	<property name="password" value="${jdbc.passWord}"></property>
<!-- 注入事务管理器对象 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
	<property name="dataSource" ref="c3p0"></property>
</bean>
<!-- 配置事务管理器对哪些方法开启事务 -->
<tx:advice transaction-manager="transactionManager" id="transacTion">
	<tx:attributes>
		<tx:method name="transfer" />
	</tx:attributes>
</tx:advice>
<!-- 切点 -->
<aop:config>
	<aop:pointcut expression="execution(* com.edu.serviceImp.TransferServiceImp.transfer(..))" id="transfer"/>
	<!-- 针对事务的配置标签 -->
	<aop:advisor advice-ref="transacTion" pointcut-ref="transfer"/>
</aop:config>
spring 事务注解加xml配置方式
<!-- 加载外部配置文件,jdbc.properties -->
<context:property-placeholder location="classpath:jdbc.properties" />
<!-- c3p0连接池提供给JdbcTemplate -->
<bean id="c3p0" class="com.mchange.v2.c3p0.ComboPooledDataSource">
	<property name="driverClass" value="${jdbc.driver}"></property>
	<property name="jdbcUrl" value="${jdbc.url}"></property>
	<property name="user" value="${jdbc.userName}"></property>
	<property name="password" value="${jdbc.passWord}"></property>
</bean>
<!-- 注入事务管理器对象 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
	<property name="dataSource" ref="c3p0"></property>
</bean>
<!-- 开启声明式事务 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
<!-- 自己的类,直接开启注解扫描器 -->
<context:component-scan base-package="com.edu"/>

使用方式:在需要开启事务的方法或者类上加上注解@Transactional

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值