zoukankan      html  css  js  c++  java
  • Spring核心概念之AOP

    一、AOP 的概念

    AOP(Aspect Oriented Programming)的缩写,面向切面编程,主要作用就是对代码进行增强处理。

    理解面向切面编程的含义:就是在不改变原有程序的基础上为代码增加新的功能。

    实现面向切面编程需要了解两个概念:

    >切入点:可以插入增强处理的方法,比如原对象的fun()方法。

    >增强处理类型:在原对象fun()方法之前还是之后插入新功能。

    二、Spring AOP简单应用

    1.新建一个java项目

    2.到官网下载Spring AOP和AspectJ框架所需要的jar包,并将下载所需的jar文件添加到项目中。

    3.在项目中添加User实体类

    package com.jbit.fsd.entity;
    
    public class User {
    
    	private int id;
    	private String username;
    	public int getId() {
    		return id;
    	}
    	public void setId(int id) {
    		this.id = id;
    	}
    	public String getUsername() {
    		return username;
    	}
    	public void setUsername(String username) {
    		this.username = username;
    	}
    	
    }
    

    4.添加数据访问层接口和实现类,并添加相应的方法

    package com.jbit.fsd.dao;
    
    import java.util.List;
    
    import com.jbit.fsd.entity.User;
    // 数据访问层接口
    public interface UserDao {
    
    	public List<User> getAll();
    	
    	public void addUser(User user);
    }
    

    实现类:

    package com.jbit.fsd.dao.impl;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import com.jbit.fsd.dao.UserDao;
    import com.jbit.fsd.entity.User;
    
    public class UserDaoImpl implements UserDao {
    
    	@Override
    	public List<User> getAll() {
    		//操作数据库读到所有数据
    		List<User> list=new ArrayList<User>();
    		list.add(new User());
    		list.add(new User());
    		list.add(new User());
    		return list;
    	}
    
    	@Override
    	public void addUser(User user) {
    		System.out.println("添加成功");
    	}
    
    }
    

    5.添加业务处理层接口和实现类

    package com.jbit.fsd.service;
    
    import java.util.List;
    
    import com.jbit.fsd.dao.UserDao;
    import com.jbit.fsd.entity.User;
    
    public interface UserService {
    
    	public List<User> getAll();
    	
    	public void addUser(User user);
    	
    	
    }
    

    实现类:

    package com.jbit.fsd.service.impl;
    
    import java.util.List;
    
    import com.jbit.fsd.dao.UserDao;
    import com.jbit.fsd.entity.User;
    import com.jbit.fsd.service.UserService;
    
    public class UserServiceImpl implements UserService{
    	private UserDao dao;
    	//通过spring注入进来
    	public void setDao(UserDao dao) {
    		this.dao = dao;
    	}
    
    	@Override
    	public List<User> getAll() {
    		System.out.println("正在执行添加用户的业务!");
    		return dao.getAll();
    	}
    
    	@Override
    	public void addUser(User user) {
    System.out.println("正在执行添加用户的业务!"); dao.addUser(user); } }

    6.添加AOP增强处理类

    package com.jbit.fsd.aop;
    
    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    
    public class ServiceLoging {
    	private Log log = LogFactory.getLog(this.getClass());
    
    	public void beforeService(){
    		log.info("aop方法被调用!");
    	}
    }
    

    7.在src目录下新建applicationContext.xml文件

    <?xml version="1.0" encoding="UTF-8"?>
    
    <!--
      - Application context definition for JPetStore's business layer.
      - Contains bean references to the transaction manager and to the DAOs in
      - dataAccessContext-local/jta.xml (see web.xml's "contextConfigLocation").
      -->
    <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:tx="http://www.springframework.org/schema/tx"
    		xsi:schemaLocation="
    			http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
    			http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
    			http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
    		<!-- 以面向接口思想编程实现解耦和 -->
    	<bean id="userDao" class="com.jbit.fsd.dao.impl.UserDaoImpl">
    	</bean>
    	<bean id="userServiceImpl" class="com.jbit.fsd.service.impl.UserServiceImpl">
    		<property name="dao" ref="userDao"></property>  <!-- 属性注入 -->
    	</bean>
    	<!-- 配置切面 -->
    	<bean id="serviceLogging" class="com.jbit.fsd.aop.ServiceLoging"></bean>
    	<aop:config>
    		<!-- 配置切入点 -->
    		<aop:pointcut expression="execution(public void  addUser(com.jbit.fsd.entity.User))" id="servicePointcut"/>
    		<!-- 将切面和切入点编制在一起-->
    		<aop:aspect ref="serviceLogging">
    			<aop:before method="beforeService" pointcut-ref="servicePointcut"/>
    		</aop:aspect>
    	</aop:config>
    </beans>
    

    8.main方法测试:

    package com.jbit.fsd.test;
    
    import java.util.List;
    
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    import com.jbit.fsd.dao.UserDao;
    import com.jbit.fsd.entity.User;
    import com.jbit.fsd.printer.Printer;
    import com.jbit.fsd.service.UserService;
    import com.jbit.fsd.service.impl.UserServiceImpl;
    
    public class Test {
    
    	/**
    	 * @param args
    	 */
    	public static void main(String[] args) {
    		ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
    		UserService dao=(UserService) ac.getBean("userServiceImpl");
    		dao.addUser(new User());
    	}
    
    }
    

    说明:

    1.在.xml文件中需要添加aop命名空间,导入与aop配置相关的标签。

    2.AOP相关的配置在<aop:config>标签中,切入点的配置在<aop:pointcut>标签中。

    3.execution是切入点的标识符,括号是切入点的表达式,配置需要增强的方法。

    4.切入点表达式常用几种模糊匹配方式:

    >public * addUser(com.able.entity.User),“*”表示配置所有类型的返回值。

    >public void * (com.able.entity.User), "*"代表匹配所有的方法名。

    >public void addUser(..),  " .. "表示匹配所有参数个数和类型。

    > * com.able.service.*.*( . . ),  表示匹配com.able.service包下面所有类的所有方法。

    > * com.able.service . . *(), 表示匹配com.able.service包以及子包下所有类的所有方法。

    三、增强处理类型简介

    1.前置增强处理

    特点:在目标方法前织入增强处理。

    <aop:before method="beforeService" poontcut-ref="servicePointcut"/>

    如果想在这个方法中获得切入点的信息,使用如下方法:

    package com.jbit.fsd.aop;
    
    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    import org.aspectj.lang.JoinPoint;
    
    public class ServiceLoging {
    	private Log log = LogFactory.getLog(this.getClass());
    
    	public void beforeService(JoinPoint joinPoint){
    		System.out.println("aop方法被调用");
    		System.out.println("连接点对象:"+joinPoint.getTarget().getClass().getSimpleName());
    		System.out.println("连接点方法:"+joinPoint.getSignature());
    		System.out.println("连接点方法参数:"+joinPoint.getArgs()[0]);
    		
    	}
    }
    

    2.后置增强处理

    特点:在目标方法正常执行(不出现异常)后织入增强处理。

    <aop:after-returning method="afterReturning" pointcut-ref="servicePointcut"/>

    如果需要获取返回值,添加returning="returnVal"

    <aop:after-returning method="aft" pointcut-ref="ser" returning="returnVal"/>

    public void afterService(Object returnVal){
    		System.out.println(returnVal);
    	}
    

    3.异常增强处理

    特点:在目标方法出现异常后织入增强处理。

    <aop:after-throwing mehod=" " pointcut-ref=" " throwing ="ex"/>

    如果需要获取异常对象才添加throwing="ex"

    public void afterThrowing(Exception ex){
    		System.out.println(ex.getMessage());
    	}
    

    4.最终增强处理

    特点:不论方法是否抛异常,都会在目标方法最后织如增强处理,类似与finally。

    <aop:after method="after" pointcut-ref="servicePointcut"/>

    5.环绕增强处理

    特点:在目标方法的前后都可以织入增强处理。

    <aop:around method="" pointcut-ref="" />

    public Boolean around(ProceedingJoinPoint pjp) throws Throwable{
    		System.out.println("目标方法的参数:"+pjp.getArgs()[0]);
    		Boolean b = null;
    		if (true) {
    			b = (Boolean) pjp.proceed(pjp.getArgs());
    		}
    		return b;
    		
    	}
    

    四、使用AspectJ 简化AOP配置

    Spring的AOP配置常有两种方式:

    >通过schema形式实现简单AOP配置,也就是上面事例使用方法。

    >使用annotation简化AOP配置。

    AspectJ是一个面向切面的框架,AspectJ定义了AOP语法。

    使用@AspectJ必须使用jdk5.0以上版本。

    步骤:

    1.编写业务类(与上面方法相同)。

    2.编写切面类。

    package com.jbit.ssh.aop;
    
    import org.aspectj.lang.annotation.After;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    
    @Aspect    //1.通过注解标记一个切面
    public class AspectTest {
    	
    	@Before("execution(* com.jbit.ssh.service..*.*(..))")//2.定义切点和增强类型(切点表达式)
    	public void ba(){  //3.增强处理的fun   4.配置xml
    		System.out.println("前置增强-------");
    	}
    	@After("execution(* com.jbit.ssh.service..*.*(..))")
    	public void aa(){
    		System.out.println("后置增强------");
    	}
    	/**
    	 * @before表示前置增强
    	 * @AfterReturning:表示后置增强处理
    	 * @Around:表示环绕增强处理
    	 * @AfterThrowing:表示异常增强处理
    	 * @After:表示最终增强处理
    	 */
    
    }
    

    3.编写配置文件实现AOP

    <?xml version="1.0" encoding="UTF-8"?>
    
    <!--
      - Application context definition for JPetStore's business layer.
      - Contains bean references to the transaction manager and to the DAOs in
      - dataAccessContext-local/jta.xml (see web.xml's "contextConfigLocation").
      -->
    <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:tx="http://www.springframework.org/schema/tx"
    		xmlns:p="http://www.springframework.org/schema/p"
    		xmlns:context="http://www.springframework.org/schema/context"
    		xsi:schemaLocation="
    			http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
    			http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
    			http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
    			http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd" >
    
    	
    	 <!--4.基于@AspectJ切面的驱动器 -->
    	<aop:aspectj-autoproxy />
    	<bean class="com.jbit.ssh.aop.AspectTest"></bean>
    </beans>
    

      

  • 相关阅读:
    jQuery Dialog and timepicker显示层的问题
    js、PHP将分数字符串转换为小数
    jqgrid动态显示/隐藏某一列
    Oracle查询每天固定时间段的数据
    Python安装pandas
    Python version 2.7 required, which was not found in the registry
    python刷剑指offer(1-20)(一刷)
    图像预处理(含计算机视觉概述)
    案例分析
    (七)目标检测算法之SSD
  • 原文地址:https://www.cnblogs.com/ablejava/p/5676938.html
Copyright © 2011-2022 走看看