标签:autowired 配置 方便 分享 针对 logger erb 详细 lib
Spring的AOP的底层用到了两种代理机制:
例如有如下一个类:
public class User { public void add() { } public void update() { } public void delete() { } }
下面是用比较通俗易懂的话来阐述AOP开发中的常见的相关术语:
增强/通知:比如增强User类里面的add方法,在add方法中添加了日志功能,这个日志功能就称为增强。
通知类型:
AspectJ是一个面向切面的框架,它扩展了Java语言。AspectJ定义了AOP语法所以它有一个专门的编译器用来生成遵守Java字节编码规范的Class文件。AspectJ是一个基于Java语言的AOP框架。Spring2.0以后新增了对AspectJ切点表达式的支持。@AspectJ是JDK5新增的功能,通过JDK5注解技术,允许直接在Bean类中定义切面。新版本Spring框架,建议使用AspectJ方式来开发AOP,使用AspectJ需要导入Spring AOP和AspectJ相关的Jar包。
从上面的阐述中,我们应认识到AspectJ并不是Spring框架的一部分,而是一个单独的面向切面的框架,只不过它经常和Spring框架一起使用进行AOP的操作而已。
使用AspectJ方式来开发AOP共有两种方式:
第一步,引入相应的Jar包
上面我说过,除了导入最基本的Jar包外,使用AspectJ还需要导入Spring AOP和AspectJ相关的Jar包。
第二步,编写目标类
在src目录下创建一个cn.itcast.aop包,并在该包下编写一个目标类。
public class Book { public void add() { System.out.println("book add................."); } }
第三步,创建增强的类以及增强的方法
public class MyBook { // 前置通知 public void before1() { System.out.println("before........"); } }
我们现在要求在Book类里面的add方法之前执行MyBook类里面的before1的方法。
第四步,在Spring配置文件中进行配置
<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" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- book对象 --> <bean id="book" class="cn.itcast.aop.Book"></bean> <bean id="myBook" class="cn.itcast.aop.MyBook"></bean>
<!-- 配置AOP的操作 --> <aop:config> <!-- 配置切入点,对Book类里面的所有方法都增强 --> <aop:pointcut expression="execution(* cn.itcast.aop.Book.*(..))" id="pointcut1"></aop:pointcut> <!-- 配置切面 aop:aspect标签里面使用属性ref,ref属性值写增强类的bean的id值 --> <aop:aspect ref="myBook"> <!-- 增强类型 method属性:增强类的方法名称 pointcut-ref属性:切入点的id值 --> <!-- 前置通知 --> <aop:before method="before1" pointcut-ref="pointcut1"></aop:before> </aop:aspect> </aop:config>
第五步,编写一个单元测试类并进行测试
在cn.itcast.aop包下编写一个TestDemo单元测试类。
public class TestDemo { @Test public void testUser() { ApplicationContext context = new ClassPathXmlApplicationContext("bean2.xml"); Book book = (Book) context.getBean("book"); book.add(); } }
其实我们也可以整合Junit单元测试,Spring对Junit4进行了支持,可以通过注解方便的测试Spring程序,所以就不必写那么麻烦的单元测试类了。首先导入如下Jar包:
然后编写如下的单元测试类:
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("/bean2.xml") // 或者也可写为:@ContextConfiguration("classpath:bean2.xml") public class TestDemo { @Autowired private Book book; @Test public void demo1() { book.add(); } }
先将MyBook增强类的代码修改为:
public class MyBook { // 前置通知 public void before1() { System.out.println("before........"); } // 后置通知 public void after11() { System.out.println("after..........."); } // 环绕通知 public void around1(ProceedingJoinPoint joinPoint) throws Throwable { System.out.println("方法之前执行..........."); // 让被增强的方法执行 joinPoint.proceed(); System.out.println("方法之后执行..........."); } }
然后再在Spring配置文件中进行配置。
<!-- 配置AOP的操作 --> <aop:config> <!-- 配置切入点,对Book类里面的所有方法都增强 --> <aop:pointcut expression="execution(* cn.itcast.aop.Book.*(..))" id="pointcut1"></aop:pointcut> <!-- 配置切面 aop:aspect标签里面使用属性ref,ref属性值写增强类的bean的id值 --> <aop:aspect ref="myBook"> <!-- 增强类型 method属性:增强类的方法名称 pointcut-ref属性:切入点的id值 --> <!-- 前置通知 --> <aop:before method="before1" pointcut-ref="pointcut1"></aop:before> <!-- 后置通知 --> <aop:after-returning method="after11" pointcut-ref="pointcut1"></aop:after-returning> <!-- 环绕通知 --> <aop:around method="around1" pointcut-ref="pointcut1"></aop:around> </aop:aspect> </aop:config>
通过execution函数,可以定义切点的方法切入。
语法为:execution(<访问修饰符>?<返回类型><方法名>(<参数>)<异常>)
。
例如:
execution(public *.*(..))
execution(* cn.itcast.dao.*(..))
,但不包含子包execution(* cn.itcast.dao..*(..))
,..*
表示包、子孙包下所有类。execution(* cn.itcast.service.UserService.*(..))
execution(* cn.itcast.dao.GenericDAO+.*(..))
execution(* save*(..))
execution(* *.*(..))
在项目开发中,我们通常会导入类似这样的日志Jar包:
使用Log4j,可以查看到当前运行程序中对象创建的过程,也可以看到更详细的信息。Log4j适合使用在程序调试中。
例如,在本文中讲解上面的Web项目使用Log4j。
首先导入log4j的jar包,如下:
然后添加log4j配置文件——log4j.properties,添加到src目录下面,该文件内容如下:
### direct log messages to stdout ### log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.Target=System.err log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n ### direct messages to file mylog.log ### log4j.appender.file=org.apache.log4j.FileAppender log4j.appender.file.File=d\:mylog.log log4j.appender.file.layout=org.apache.log4j.PatternLayout log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n ### set log levels - for more verbose logging change ‘info‘ to ‘debug‘ ### log4j.rootLogger=info, stdout, file
粗略讲解如下图:
创建一个Web项目, 引入相关的jar包。所要导入的jar包如下:
引入Spring的配置文件。主要引入AOP的约束:
<?xml version="1.0" encoding="UTF-8"?> <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" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> </beans>
编写目标类。
在Web项目的src目录下创建一个cn.itcast.aop包,并在该包下编写一个Book类:
public class Book { public void add() { System.out.println("book add................."); } }
编写切面类。
再在cn.itcast.aop包下编写一个MyBook增强类:
public class MyBook { public void before1() { System.out.println("before........"); } }
在增强的类上面使用@Aspect
注解
@Aspect public class MyBook { public void before1() { System.out.println("before........"); } }
在增强类的方法里面,使用注解配置通知类型:
@Aspect public class MyBook { // 前置通知 // *:方法的访问修饰符,也可写为execution(public void cn.itcast.aop.Book.*(..)),但一般都不会用 @Before("execution(* cn.itcast.aop.Book.*(..))") public void before1() { System.out.println("before........"); } }
AspectJ的AOP的注解:
@Aspect
:定义切面类的注解@Before
:前置通知,相当于BeforeAdvice@AfterReturning
:后置通知,相当于AfterReturningAdvice@Around
:环绕通知,相当于MethodInterceptor@AfterThrowing
:抛出通知,相当于ThrowAdvice@After
:最终final通知,不管是否异常,该通知都会执行@Pointcut
:定义切入点的注解开启AspectJ的注解
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
创建Book类和MyBook类的两个对象(使用配置文件)
<bean id="book" class="cn.itcast.aop.Book"></bean> <bean id="myBook" class="cn.itcast.aop.MyBook"></bean>
最后在cn.itcast.aop包下编写一个TestDemo单元测试类
public class TestDemo { @Test public void testBook() { ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml"); Book book = (Book) context.getBean("book"); book.add(); } }
标签:autowired 配置 方便 分享 针对 logger erb 详细 lib
原文地址:https://www.cnblogs.com/qinjf/p/9053744.html