`

学习Spring笔记_AOP_Annotation实现和XML实现

阅读更多

 

鸣谢:感谢北京尚学堂马士兵老师的视频教程。

 

实现AOP需要加入aspectj的两个JAR包:aspectjweaver.jar, aspectjrt.jar

 

当要对没有实现接口的类实现动态代理,需要引入CGLIB的JAR包:cglib-nodep-2.1_3.jar

 

AOP的Annotation实现方式:

    必须在配置文件中加入<aop:aspectj-autoproxy/>标签,加入该标签后才能在源代码中使用Annotation的方式实现动态代理。

    要想使用<aop:aspectj-autoproxy/>标签,必须在beans标签中加入以下属性:

xmlns:aop=http://www.springframework.org/schema/aop

http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd

 

具体实现代码段如下:

beans.xml

<?xml version="1.0" encoding="UTF-8"?>
<!-- spring2.5配置文件固定写法 -->
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       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">
  
  <!-- 加入此配置就可以在源码中写Annotation(注解),注解编程 -->
  <context:annotation-config />
  <!--
    使用此配置代码,spring会自动扫描com.yusj包下的所有带@component注解的Class文件
    @Component包括:@controller,@service,@repository和@component
    当分不清楚Class具体要做什么工作时,可以统一写成@component.
    @controller:一般写在控制层。
    @service:一般写在服务层。
    @repository:一般写在持久层,也就是DAO。
    @component (把普通pojo实例化到spring容器中,相当于配置文件中的<bean id="" class=""/>
   -->
  <context:component-scan base-package="com.yusj" />
  <!-- 加入此配置就可以在源代码中写关于AOP(aspectj)的Annotation(注解)了。 -->
  <aop:aspectj-autoproxy />
  
</beans>

 LogInterceptor.java(织入类):

package com.yusj.aop;

import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

/**
 * 为某些切入点植入新的方法
 * 必要条件:
 *    1. 源方法与目标方法必须都被Spring容器管理
 *    2. 在类名上方加入@Component和@Aspect注解 
 * @author yushaojian
 *
 */
@Component
@Aspect
public class LogInterceptor {
	/**
	 * 在com.yusj.dao.IUserDAO.save方法执行前,执行doBefore方法
	 */
	@Before("execution(public void com.yusj.dao.IUserDAO.save(com.yusj.model.User))")
	public void doBefore(){
		System.out.println("save start ...") ;
	}
	/**
	 * 在com.yusj.dao包下所有类的所有方法正式执行之后再执行afterReturning方法
	 */
	@AfterReturning("execution(* com.yusj.dao..*.*(..))")
	public void afterReturning(){
		System.out.println("save after returning ...") ;
	}
}

 Test.java:

package com.yusj.spring;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Component;

import com.yusj.model.User;
import com.yusj.service.IUserService;

public class Test {

	public static void main(String[] args) {
		
		/**
		 * Spring提供的读取配置文件方法,此处推荐使用ApplicationContext而非BeanFactory.
		 * beans配置文件默认读取src根目录文件名相同的XML文件
		 * 如果需要放在特殊的位置,那么需要指定具体路径,比如:com/yusj/xml/beans.xml
		 * 
		 */
		ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
		/**
		 * 获取UserServiceImpl.java中利用@Component("usi")自动装载的bean
		 * 
		 */
		IUserService service = (IUserService) ctx.getBean("usi");
		// 初始化用户并赋值
		User u = new User();
		u.setUsername("张三");
		u.setPassword("zhangsan");
		// 添加用户测试
		service.add(u);
		/**
		 * 输出结果:
		 * save start ...
		 * user save success...
		 * User [username=张三, password=zhangsan]
		 * save after returning ...
		 */
	}
}

 

XML配置实现: 

beans.xml(去掉<aop:aspectj-autoproxy/>标签):

<?xml version="1.0" encoding="UTF-8"?>
<!-- spring2.5配置文件固定写法 -->
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       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">
  
  <!-- 加入此配置就可以在源码中写Annotation(注解),注解编程 -->
  <context:annotation-config />
  <!--
    使用此配置代码,spring会自动扫描com.yusj包下的所有带@component注解的Class文件
    @Component包括:@controller,@service,@repository和@component
    当分不清楚Class具体要做什么工作时,可以统一写成@component.
    @controller:一般写在控制层。
    @service:一般写在服务层。
    @repository:一般写在持久层,也就是DAO。
    @component (把普通pojo实例化到spring容器中,相当于配置文件中的<bean id="" class=""/>
   -->
  <context:component-scan base-package="com.yusj" />
  
  <!-- 定义切面类的Bean -->
  <bean id="logInterceptor" class="com.yusj.aop.LogInterceptor" />
  <!-- 配置AOP -->
  <aop:config>
    <!-- 定义全局的pointcut,所有的代理过滤条件都参照此pointcut -->
    <aop:pointcut expression="execution(public void com.yusj.dao.IUserDAO.save(com.yusj.model.User))" id="userDAOPointcut"/>
    <!-- 把标准Bean与AOP-aspect做关联,标准Bean就成为具有aspect(切面织入)功能的Bean -->
    <aop:aspect id="logAspect" ref="logInterceptor">
      <!-- 
        pointcut-ref : 过滤需要代理的方法的切入点,此例中是为IUserDAO.save方法加入代理.
          关联方法:通过pointcut-ref属性,找到aop:pointcut中的expression属性来实现过滤.
        method : 在pointcut-ref所指定方法执行前,执行com.yusj.aop.LogInterceptor.doBefore方法.
          关联方法:因为aop:before标签是在aop:aspect标签中,所以通过aop:aspect的ref属性找到Bean(com.yusj.aop.LogInterceptor).
       -->
      <aop:before method="doBefore" pointcut-ref="userDAOPointcut"/>
    </aop:aspect>
  </aop:config>
  
</beans>

 LogInterceptor.java(去掉所有Annotation,在XML中定义Bean):

package com.yusj.aop;

import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

/**
 * 用XML实现,切面类不用做特殊处理 
 * @author yushaojian
 *
 */
public class LogInterceptor {
	public void doBefore(){
		System.out.println("save start ...") ;
	}
	public void afterReturning(){
		System.out.println("save after returning ...") ;
	}
}

 Test.java:

package com.yusj.spring;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Component;

import com.yusj.model.User;
import com.yusj.service.IUserService;

public class Test {

	public static void main(String[] args) {
		
		/**
		 * Spring提供的读取配置文件方法,此处推荐使用ApplicationContext而非BeanFactory.
		 * beans配置文件默认读取src根目录文件名相同的XML文件
		 * 如果需要放在特殊的位置,那么需要指定具体路径,比如:com/yusj/xml/beans.xml
		 * 
		 */
		ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
		/**
		 * 获取UserServiceImpl.java中利用@Component("usi")自动装载的bean
		 * 
		 */
		IUserService service = (IUserService) ctx.getBean("usi");
		// 初始化用户并赋值
		User u = new User();
		u.setUsername("张三");
		u.setPassword("zhangsan");
		// 添加用户测试
		service.add(u);
		/**
		 * 输出结果:
		 * save start ...
		 * user save success...
		 * User [username=张三, password=zhangsan]
		 */
	}
}

 

 

eclipse项目导出见附件(Export -> General -> File System):

 

0
0
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics