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>
    

      

  • 相关阅读:
    Unity The Method Signature Matching Rule
    Unity The Property Matching Rule
    Unity The Type Matching Rule
    Unity The Custom Attribute Matching Rule
    Unity The Member Name Matching Rule
    Unity No Policies
    Unity The Return Type Matching Rule
    Unity The Parameter Type Matching Rule
    Unity The Namespace Matching Rule
    关于TSQL递归查询的(转)
  • 原文地址:https://www.cnblogs.com/ablejava/p/5676938.html
Copyright © 2011-2022 走看看