`
log_cd
  • 浏览: 1098565 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

使用AspectJ LTW(Load Time Weaving)

阅读更多
    在Java 语言中,从织入切面的方式上来看,存在三种织入方式:编译期织入、类加载期织入和运行期织入。编译期织入是指在Java编译期,采用特殊的编译器,将切面织入到Java类中;而类加载期织入则指通过特殊的类加载器,在类字节码加载到JVM时,织入切面;运行期织入则是采用CGLib工具或JDK动态代理进行切面的织入。
    AspectJ采用编译期织入和类加载期织入的方式织入切面,是语言级的AOP实现,提供了完备的AOP支持。它用AspectJ语言定义切面,在编译期或类加载期将切面织入到Java类中。
    AspectJ提供了两种切面织入方式,第一种通过特殊编译器,在编译期,将AspectJ语言编写的切面类织入到Java类中,可以通过一个Ant或Maven任务来完成这个操作;第二种方式是类加载期织入,也简称为LTW(Load Time Weaving)。
    使用AspectJ LTW有两个主要步骤,第一,通过JVM的-javaagent参数设置LTW的织入器类包,以代理JVM默认的类加载器;第二,LTW织入器需要一个 aop.xml文件,在该文件中指定切面类和需要进行切面织入的目标类。

    设置-javaagent JVM参数的方法:
(1)在Eclipse下的设置:
运行类->右键单击->Run As->Run...,可以在弹出的Run设置窗口设置该类的各项运行属性,切换到Arguments Tab页,在VM arguments中通过-javaagent指定AspectJ 织入器类包。-javaagent:E:\workspace\lib\spring2.5\aspectjweaver.jar
(2)在Tomcat下的设置
打开<Tomcat_Home>\bin\catalina.bat,在该批处理文件头部添加以下的设置:
set JAVA_OPTS=-javaagent:E:\workspace\lib\spring2.5\aspectjweaver.jar

一、配置LTW织入器的aop.xml配置文件
    LTW织入器在工作时,首先会查找类路径下META-INF /aop.xml的配置文件,并根据配置文件的设置进行织入的操作。
<?xml version="1.0" encoding="UTF-8"?>
<aspectj>
	<aspects>
		<!-- ①切面类 -->
		<aspect name="quickstart.aspectj.Monitor" />
	</aspects>
	<weaver
		options="-showWeaveInfo -XmessageHandlerClass:org.springframework.aop.aspectj.AspectJWeaverMessageHandler">
		<!-- ② 指定需要进行织入操作的目标类范围 -->
		<include within="quickstart.service..*" />
	</weaver>
</aspectj>

二、切面织入的目标类和切面实例
package quickstart.service.impl;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import quickstart.dao.PersonDao;
import quickstart.model.Person;
import quickstart.service.PeopleService;

public class PeopleServiceImpl implements PeopleService{
	
	//通过类型(byType为默认)的自动连接可能会有多个候选,
	//通过使用@Qualifier注解,使用名称(byName)来限定
	@Autowired
	@Qualifier("personDao")
	private PersonDao personDao;
	
	@Transactional(propagation = Propagation.REQUIRED)
	public void savePerson(Person person) {
		personDao.save(person);
	}

	@Transactional(readOnly = true, propagation = Propagation.REQUIRED)
	public Person findPersonById(Integer id) {
		return personDao.findById(id);
	}

	@Transactional(readOnly = true, propagation = Propagation.REQUIRED)
	public List findPersonByJPQL(String jpql){
		return personDao.findByJPQL(jpql);
	}

package quickstart.aspectj;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class Monitor {

	@Pointcut("execution(* quickstart.service.impl.*.*(..))")
	public void anyService(){}

	
	@Before("quickstart.aspectj.Monitor.anyService()")
	public void log(JoinPoint joinPoint){
		System.out.println("Service Method " + joinPoint.getSignature().getName() + " Invocation!");
	}
}

三、Spring配置文件applicationContext.xml
<?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"
    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.0.xsd
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">

	<!-- 需要指定factory-method="aspectOf"属性,以便确保Spring从AspectJ获取切面实例,而非自己创建该实例。 -->
	<bean id="momitor" class="quickstart.aspectj.Monitor"  factory-method="aspectOf"/>
	
	<!-- 自动装配注解Bean后置处理器 -->
	<bean 
		class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
    
    <!-- JPA注解Bean后置处理器 -->
    <bean
        class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />

	<!-- 利用Spring的实体管理器工厂来创建JPA实体管理器 -->
    <bean id="entityManagerFactory"
        class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="jpaVendorAdapter">
            <bean
                class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
                <property name="database" value="MYSQL" />
                <property name="showSql" value="true" />
                <!-- <property name="generateDdl" value="true" /> -->
            </bean>
        </property>
    </bean>

    <bean id="dataSource"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <property name="url" value="jdbc:mysql://localhost/test?useUnicode=true&amp;characterEncoding=UTF-8" />
        <property name="username" value="root" />
        <property name="password" value="root" />
    </bean>
	
	<!-- 声明一个Spring提供的JPA事务管理器,传入的参数是Spring中的实体管理器工厂 --> 
    <bean id="transactionManager"
        class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory" />
    </bean>

	<!-- 开启Spring提供的基于注解的声明式事务管理 -->
    <tx:annotation-driven transaction-manager="transactionManager" />
 	
 	<!-- 直接使用Spring的 JpaTemplate -->
	<bean id="jpaTemplate" class="org.springframework.orm.jpa.JpaTemplate">
		<property name="entityManagerFactory" ref="entityManagerFactory" />
	</bean>

	<bean id="personDao" class="quickstart.dao.impl.PersonDaoImpl" autowire="byName"/>
	
	<bean id="peopleService" class="quickstart.service.impl.PeopleServiceImpl"/>
</beans>

四、测试
package logcd.test;

import java.util.List;

import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import quickstart.model.Address;
import quickstart.model.Person;
import quickstart.service.PeopleService;


public class JpaServiceTest {

	private static ApplicationContext appContext;
	private static PeopleService peopleService;
	
	@BeforeClass  
	public static void Init(){   
		appContext = new ClassPathXmlApplicationContext("applicationContext.xml");
		peopleService = (PeopleService)appContext.getBean("peopleService");
	} 
	
	@Test
	public void findById(){
		Person person = peopleService.findPersonById(new Integer(2));
		System.out.println(person.getFirstName()+person.getLastName());
		//System.out.println(person.getAddress().getStreetName());
	}
	
	@Test
	public void findByJPQL(){
		StringBuilder jpql = new StringBuilder();
		jpql.append(" FROM Person p JOIN FETCH p.address");
		List list = peopleService.findPersonByJPQL(jpql.toString());
		for(Object obj : list){
			Person person = (Person)obj;
			System.out.println(person.getFirstName() + person.getLastName());
			System.out.println(person.getAddress().getStreetName());
		}
	}
}

分享到:
评论

相关推荐

    spring-loadtime-weaving-example:使用AspectJ的Spring Boot加载时编织示例

    使用AspectJ的Spring Boot加载时编织示例 这是一个用AspectJ编织Spring Boot加载时间的示例。 这是前面的的延续。 加载时间编织 加载时编织是一种二进制编织,其中已编译的Java类在运行时(而不是编译时)作为输入。...

    spring-aspectj-ltw-xml-based-demo

    Spring支持运行时织入(Runtime Weaving, LTW),这通常通过加载时织入(Load-Time Weaving, LTW)实现,无需修改字节码或重新编译源码。 在"spring-aspectj-ltw-xml-based-demo"中,"applicationContext.xml"文件...

    AspectJ的jar包

    加载时织入则是在类加载到JVM时动态地修改字节码来实现的,这需要使用特定的类加载器和AspectJ的ltw(Load-Time Weaving)库。 标签"Aspect"表明这个话题主要关注的是面向切面编程,这是软件设计的一个重要概念,...

    aspectj,aspectjrt,weaver等

    AspectWeaver 有两种主要模式:一种是LTW(Load-Time Weaving),它在类加载到JVM时进行织入;另一种是AJDT(AspectJ Development Tools)在Eclipse IDE中的支持,可以进行编译时织入。在Spring中,通常会使用LTW ...

    AspectJ_sample:AspectJ示例

    3. **加载时编织(Load-Time Weaving, LTW)**: `AspectJLTWSample`展示了加载时编织的概念。在程序运行时,AspectJ织入切面到已加载的类中。这通常需要一些额外的配置,例如使用AspectJ的Java Agent或者Spring ...

    AspectJ.rar

    而加载时织入则是在运行时由类加载器完成切面的织入,这通常需要额外的配置,如使用AspectJ的LTW(Load-Time Weaving)代理。 "AspectJ.rar"这个压缩包可能包含了AspectJ的相关库文件,用于在Spring项目中实现AOP...

    book :aspectj in action

    此外,书中可能还提到了AspectJ的开发和调试工具,如AspectJ Weaver和LTW(Load-Time Weaving),它们可以帮助开发者在运行时动态地编织切面。 压缩包内的"Manning@2003 - AspectJ In Action.pdf"是该书的电子版,...

    aspectj-1.6.10.jar完整下载

    运行时织入则需要 AspectJ LTW(Load-Time Weaving)支持。 5. 使用工具集成: AspectJ 可以与 Eclipse、IntelliJ IDEA 等 IDE 集成,提供便捷的开发环境支持,包括自动提示、语法检查和调试等功能。 在实际项目中...

    aspectj-demo.zip

    5. **配置文件(AspectJ LTW Configuration)**: 如果是运行时织入,可能需要在项目中添加AspectJ的加载时织入(LTW, Load-Time Weaving)配置,例如在`META-INF/aop.xml`文件中定义要编织的切面。 6. **主程序(Main ...

    Aspectj驱动

    - **LTW(Load-Time Weaving)**:在程序加载时进行织入,适用于无法修改源代码或者无法使用编译时织入的情况。AspectJ的LTW可以通过Java代理机制实现。 - **CTW(Compile-Time Weaving)**:在编译阶段进行织入,...

    Manning - AspectJ in Action切面编程详解-书签文字英文版

    书中的内容不仅涵盖了AspectJ的基础概念,还包括了如何设计和实现切面、类型织入与编译时织入的区别、以及如何利用AspectJ的LTW(Load-Time Weaving)机制。此外,书中还介绍了如何集成AspectJ到Spring框架,以及...

    AspectJ In Action

    5. **高级特性探索**:包括AspectJ的类型系统增强、动态代理、LTW(Load-Time Weaving)和CTW(Compile-Time Weaving)等,这些都是提高灵活性和性能的关键技术。 6. **测试与调试**:介绍如何对AspectJ应用进行...

    com.springsource.org.aspectj.weaver-1.6.8.RELEASE 下载

    3. **LTW(Load-Time Weaving)**:AspectJ Weaver支持加载时织入,无需修改应用服务器配置,即可实现AOP功能,这为基于Java EE的应用提供了便利。 4. **强大的切点表达式(Pointcut Expressions)**:AspectJ提供...

    ASpectJ_LoginDemo.zip

    编译时织入通常通过 ajc 编译器完成,而运行时织入则使用 AspectJ 的 LTW(Load-Time Weaving)机制。 在 ASpectJ_LoginDemo 示例中,开发者可能创建了一个模拟的登录界面,然后利用 AspectJ 实现了登录验证的切面...

    aspectj-1.9.6.zip

    AspectJ 提供了两种织入方式——编译时织入(使用 ajc 编译器)和加载时织入(使用 LTW,Load-Time Weaving)。 2. **API 类库**:提供了编程接口,允许开发者创建和管理切面,包括定义切入点(Pointcut)、通知...

    aspectjrt-1.1.0.jar.zip

    此外,也可以在运行时使用AspectJ织入器(AspectJ LTW,Load-Time Weaving)动态地对类进行编织,这样无需重新编译就能实现切面效果。 "jar.zip" 文件格式是Java档案文件,它是Java平台上的标准归档格式,用于打包...

    AspectJDemo

    AspectJ提供了编译时织入(通过ajc编译器)和加载时织入(通过AspectJ LTW - Load Time Weaving)。 5. **引入(Introduction)**:引入允许你在现有的类中添加新的接口或方法,无需修改原始代码。 在...

    aspectjar包

    在集成AspectJ到项目中时,可以使用AspectJ编译器(ajc)进行编译时织入,或者在运行时使用AspectJ的LTW(Load-Time Weaving)机制。LTW可以在应用程序启动时动态地修改字节码,实现切面的织入。 "aspectjar包"的...

    Manning - AspectJ In Action source code

    静态织入通常在编译阶段完成,而动态织入则在程序运行时进行,例如通过AspectJ的LTW(Load-Time Weaving)机制。 7. **源代码结构** 压缩包中的文件名称列表表明该资源可能包含了《AspectJ实战》一书的各个章节的...

    AspectJCookBook 源码

    此外,书中还详细阐述了AspectJ的LTW(Load-Time Weaving)和CTW(Compile-Time Weaving)两种织入机制,以及它们在不同场景下的适用性。 源码文件`aspectjcookbook_examples.zip`则是对书中各种示例的实现。这些...

Global site tag (gtag.js) - Google Analytics