`
xupo
  • 浏览: 214905 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

对象缓存管理器JAVA实现(第二篇)---Implements Object Caching with AOP

阅读更多

Introduction

Object caching provides a mechanism to store frequently accessed data in memory, minimizing the calls to back-end database, and resulting in significant improvement in the application performance. It also gives us the ability to refresh different types of data at different time intervals (based on pre-defined eviction and cache refresh policies). Object caching offers several advantages with fast access to data but it also suffers from some disadvantages like memory overhead and synchronization complexity. By making caching an Aspect we get the flexibility of dynamically adding caching ability in a J2EE application for cached objects. We can also remove caching out of the application whenever it becomes a bottleneck in terms of memory usage. In this article, I will provide an example of object caching as an Aspect in J2EE applications and discuss the steps involved in injecting the caching functionality into a sample web application. I will also explain the flexibility of switching between two different caching frameworks without modifying any application code. The article uses AspectJ, with the caching logic implemented in both JBossCache and OSCache.

Caching As An Aspect

Object caching has a number of characteristics that make it a prime candidate for implementation as an Aspect. Some of these characteristics are:

  • caching code is often duplicated throughout a web application
  • it's not easy to turn caching on or off dynamically when it's part of your business logic
  • caching logic does not provide any business functionality, it's not related to the domain of a business application 

This article assumes that reader has a basic understanding of Aspects and AOP concepts. Those who are new to Aspects should review the Appendix section at the end of the article for a brief overview of AOP and definitions of AOP components.

In the traditional approach to object caching, objects are stored in memory (cache) after first use, and then reused for subsequent data access requests instead of making costly data source calls. The cached data is released from memory (purged), by implementing a pre-defined eviction policy, when the data is no longer needed.

For an Aspect-based approach, we need to first write a pointcut to intercept the actual data load method called by a client program. Then we write an "around" advice to query the cache for a matching data based on a cache key. If no data match is found, the advice uses proceed() (which is similar to calling the load method in cache loader class) to execute the data access operation and inserts the data returned from the datastore into cache. Finally, the advice returns the object obtained from the cache if the data already exists in cache or newly created object if cache didn't have it in the first place.

Compared to traditional caching implementation, a cache loader class is not really necessary in aspect oriented caching solution. This is because with a caching aspect we have access to the calling class and its methods via the pointcut, so we know which method to call to retrieve the data from back-end data store.

Following table summarizes the steps involved in data access calls with and without caching implementation and also using caching as an aspect:

Data Access Scenario 1 Scenario 2 Scenario 3
Type of caching No caching implemented. Traditional caching implementation. Aspect oriented caching implementation.
First request Retrieve data from database and return result to client. Check if data is in cache.
No match is found so retrieve data from database, store the result in cache, and return data to client.
Intercept the data access call using a pointcut.
Using an around advice, check if data is in cache.
No match is found so call proceed() method which in turn executes the data load method.
Store the result in cache and return data to client.
Subsequent requests Retrieve data from database again and return result to client. Check if data is in cache.
A match is found so return the data found in cache to the client.
If data in the cache is expired, retrieve data from database again, store it in cache, and return to client.
Intercept the data access call using the same pointcut.
Check if data is in cache using the around advice.
A match is found so return data to client.
Caching Logic None. Embedded in application code. Encapsulated in Aspects.
Invasive? N/A Yes (Changes in application code are necessary to enable or disable caching) No (Completely separated from the application code. Caching logic is dynamically weaved into the application)

 

Caching using JBossCache - AOP Style

I used JBossCache as the main framework to demonstrate aspect oriented object caching implementation in the sample web application. JBossCache provides two flavors of object caching implementation, TreeCache and TreeCacheAop. TreeCache is basically a structured object tree with nodes. The data stored in the cache is accessed by specifying a fully qualified name (FQN) which is the concatenation of all node names from root node to the current node. FQN is same as the region name used in other caching frameworks such as Java Caching System (JCS) and OSCache. A cache region is defined as an organizational name space for holding a collection of cache objects with similar characteristics (such as business usage and time to live). TreeCache can be used as a stand-alone cache (local) or a replicated cache (in a multi-server cluster environment). Also, the cache replication can be done asynchronously or synchronously (synchronous means the client request is not returned until all cache changes are replicated in the cluster nodes). JBossCache uses the JGroups framework for the group communication purposes when replicating the modifications in one cache to other caches in the cluster.

TreeCacheAop is an AOP-enabled extension of TreeCache. It allows for plain java objects to be stored in the cache and replicated transactionally between the nodes in a cluster. TreeCache is highly configurable in terms of replication mode (async, sync, or none), transaction isolation levels, eviction policies, and transactional management.

Object Caching Framework

The object caching framework used in this article is based on the object caching framework described in articles Object Caching in a Web Portal Application Using JCS and J2EE object-caching frameworks. Based on the requirements of caching implementation as an aspect, I have made a list of objectives that needed to be accomplished by the proposed Cache AOP framework. Following is the list of these objectives:

  1. Avoid duplicating the caching logic at every execution point in the application where there is a business case for data caching.
  2. Write cache related code in a non-intrusive way so it doesn't affect the core application code. This is because the caching logic has nothing to do with the core functionality of the application. It is used mainly for performance reasons.
  3. Ability to switch between the scenarios of running the application with and without caching, in order to assess the effectiveness of caching in data access. With the caching aspect implementation, if caching proves to be not really effective, we don't have to modify the application code by commenting or removing the caching logic. This approach is very useful during unit testing phase where we want to test the caching feature with different configuration parameters to come up with the best scenario.
  4. Flexibility to easily switch between or replace the caching implementation with a different (and better) framework without affecting the application code. There are many different algorithms and configuration settings so it takes few iterations to get optimum caching configuration and best results out of a caching implementation.
  5. Ability to trace and monitor caching statistics for better management of objects stored in the cache. We need to constantly monitor cache usage to determine how effectively caching is being used (based on cache hit to miss ratio) and make any necessary adjustments in the cache configuration or the expiration policies to keep object caching more effective and efficient. Also, as the business requirements and application functionality change over time we need to make sure we are only storing the expensive-to-access (and frequently requested data) in the cache. By encapsulating tracing and logging functions into aspects as well, we will have a non-intrusive cache monitoring capabilities where we don't have to write the tracing method calls all over in the application code to measure the effectiveness of caching.

Sample Web Application Setup

The web application used to demonstrate the caching implementation using AOP techniques is a bank application used to process home loans. In a typical loan processing application, the customer is given a list of interest rates for a specified product type before the user can actually lock a home loan. These interest rates are a perfect candidate for caching since they only change few times a day but the rate data is frequently accessed by the loan application. So, by storing interest rate details in the cache, we minimize the need to hit the data source every time a loan application is processed. There are two types of loan products used in the web application, Mortgages and Home Equity (HELOC) loans.

The interaction between different tiers in the loan application (client, web, object cache, and back-end HSQL database) is represented in the topology diagram in Figure 1.



Figure 1. Topology Diagram with Tomcat Cluster and JBossCache (Click on the screen shot to open a full-size view.)

The flow of loan processor web application is shown in the sequence diagram in Figure 2.


Figure 2. LoanApp Web Application Sequence Diagram (Click on the screen shot to open a full-size view.)

The entry point into the web application is a servlet called LoanAppServlet that gets the interest rates based on product type sent by the client (in HTTP request). The helper class LoanAppHelper has the data access methods to retrieve (using JDBC calls) the interest rates stored in a HSQL database. Following is a code snippet of getInterestRates method to get the rates from INTERESTRATES table in LoanDB database using JDBC calls.

Figure 2. LoanApp Web Application Sequence Diagram (Click on the screen shot to open a full-size view.)

The entry point into the web application is a servlet called LoanAppServlet that gets the interest rates based on product type sent by the client (in HTTP request). The helper class LoanAppHelper has the data access methods to retrieve (using JDBC calls) the interest rates stored in a HSQL database. Following is a code snippet of getInterestRates method to get the rates from INTERESTRATES table in LoanDB database using JDBC calls.

 public List getInterestRates(String prodGroup) {

      List interestRates = new ArrayList();

      Connection conn = null;
      Statement stmt = null;
      ResultSet rs = null;

      try {
         conn = DriverManager.getConnection(jdbcUrl, userName,
               password);
         sLog.debug("conn: " + conn);
         stmt = conn.createStatement();

         String sql = "SELECT * FROM InterestRates WHERE ";
               sql += "productGroup = '" + prodGroup + "'";
               rs = stmt.executeQuery(sql);

         List rates = new ArrayList();
         while (rs.next()) {
            String productType = rs.getString("productType");
            String productGroup = rs.getString("productGroup");
            double rate = rs.getDouble("rate");
            double mtgPoints = rs.getDouble("points");
            double apr = rs.getDouble("apr");

            InterestRate interestRate = new InterestRate();
            interestRate.setProductType(productType);
            interestRate.setRate(rate);
            interestRate.setPoints(mtgPoints);
            interestRate.setApr(apr);

            interestRates.add(interestRate);
         }
      } catch (SQLException e) {
         e.printStackTrace();
      } finally {
         try {
            rs.close();
            stmt.close();
            conn.close();
         } catch (Exception e) {
            //
         }
      }
      return interestRates;
   }

 

Note: Using pure JDBC calls in a real world application is not recommended. Instead, object relational modeling (ORM) tools such as Hibernate or JDO and database connection pooling (Commons DBCP) frameworks should be considered for data access requirements.

The LoanApp web application uses TreeCache (org.jboss.cache.TreeCache) class to implement caching. It also uses asynchronous replication to propagate cache changes to all nodes in the cluster. Following section describes how caching is introduced into the application using aspects.

I wrote an abstract aspect called ObjectCache to encapsulate all the cache methods (like putCacheObject, peek etc). The concrete implementations of this abstract aspect are defined in JBossCache and OSCache (for JBossCache and OSCache caching frameworks respectively). I also added two more aspects to take care of logging and tracing requirements in the web application (logging and tracing are two other popular cross-cutting concerns that are weaved into the application code via aspects).

Figure 3 shows the class diagram with the associations between java classes and aspects created in LoanApp application.

Figure 3. Cache AOP Class Diagram (Click on the screen shot to open a full-size view.)

I initialized the cache objects when the web application context (/CachingAOP) was created by Tomcat server and keep them in memory until the application context is destroyed. This is done by implementing a custom servlet context listener (LoanAppContextListener). I added pointcuts contextInitialized and contextDestroyed to take care of the instantiation and removal of cache objects when the servlet context is initialized and destroyed respectively. Following code shows how TreeCache is initialized when servlet context is loaded.

abstract pointcut contextInitialized(ServletContextEvent event);
    void around(ServletContextEvent event) : contextInitialized(event) {
        initObjectCache();
    }

 

 And here's the implementation of initObjectCache method in JBossCache aspect:

private TreeCache cache;

   public void initObjectCache() {
      try {
         cache = new TreeCache();
         PropertyConfigurator config = new PropertyConfigurator();
         config.configure(cache, "jbosscache-config.xml");
         cache.setClusterName(cacheGroupName);
         cache.createService();
         cache.startService();
         sLog.debug("cache : " + cache);
      } catch (Exception e) {
         // Handle cache region initialization failure
         sLog.debug("Error in creating JBossCache.");
         sLog.error(e);
      }
   }

 

We write a pointcut to intercept getInterestRates() method and then write an "around" advice to implement the caching logic. In the advice, we query the cache for a matching data based on productGroup cache key. Let's look at how this logic is implemented in ObjectCache aspect.

 

abstract pointcut getInterestRates(String productGroup);
   List around(String productGroup) : getInterestRates(productGroup) {
      long start = System.currentTimeMillis();

      List rateList = null;
      try {
         if (peek(productGroup) != null)
         {
            sLog.debug("Data found in cache.");
            rateList = getInterestRates(productGroup);
            return rateList;
         }
         sLog.debug("Data not found in cache.");
         rateList = proceed(productGroup);
         putCacheObject(productGroup, rateList);

         long stop = System.currentTimeMillis();
         sLog.debug("Time taken to get interest rates=" + (stop-
               start) + " ms.");

	 printCacheStatistics();
      } catch (Exception e) {
         e.printStackTrace();
      }
      return rateList;
   }

 

 

If there is a cache miss or stale hit, the advice uses proceed() to execute the data access operation (LoanAppHelper.getInterestRates() method) and inserts the data returned from the database into the cache (using putCacheObject method). Finally, the advice returns the object obtained from the cache if it already exists in the cache or newly created object if cache didn't have it in the first place.

The following table shows the details of the caching aspects and pointcuts.

Aspect PointCut Advice
ObjectCache.aj
JBossCache.aj
OSCache.aj
contextInitialized
contextDestroyed
getInterestRates
around
around
around

The AspectJ project created to run the web application code using aspects is called CacheAOP. I created separate directories under CacheAOP/WEB-INF/src folder (java, web, and aspects) to store java files and aspect files in their own directories. A link to the sample application code is included at the end of this article. To run the application, make sure you have the following JAR files specified in the classpath:

commons-logging-1.0.4.jar, junit.jar, log4j-1.2.8.jar, oscache-2.1.jar, commons-httpclient.jar, aspectjrt.jar, jgroups-2.2.7.jar, concurrent.jar, dom4j-full.jar, hsqldb.jar, jboss-aop.jar, jboss-cache.jar, jboss-common.jar, jboss-j2ee.jar, jboss-remoting.jar, jboss-system.jar, jboss-jmx.jar, and servlet-api.jar.

The config directory (located under WEB-INF) also needs to be in the classpath since all the configuration files (JBossCache, OSCache, and Log4J) are stored in this directory.

You can switch between different caching scenarios using AspectJ build properties file (build.ajproperties) created in the Eclipse project. Just open the properties file in the editor, include or exclude the aspects you would like to weave into the application code, and rebuild the project. This involves no additions or modifications in the web application code. Figure 4 shows the screenshot of build.ajproperties (AJDT) tab in Eclipse IDE with ObjectCache and JBossCache aspects selected for code weaving.

Figure 4. AspectJ Build Properties Window in Eclipse IDE (Click on the screen shot to open a full-size view.)To understand how caching is introduced in the web application, I ran the build command for the following three scenarios:

  1. Run the web application with no caching implemented.
  2. Caching is implemented using JBossCache.
  3. Caching is implemented using OSCache framework.

Cluster Details

LoanApp web application was deployed to run in a Tomcat cluster with two server instances running on a single machine. The configuration parameters used in the cluster are listed in the table below.

ParameterNode 1Node 2
Server Name TC-01 TC-02
Home Directory c:/dev/tomcat51 c:/dev/tomcat52
Web App Directory C:/dev/projects/CachingAspect/node1/CachingAOP C:/dev/projects/CachingAspect/node2/CachingAOP
Server Port 9005 10005
Connector/Port 9080 10080
Coyote/JK2 AJP Connector 9009 10009
Cluster mcastAddr 228.0.0.4 228.0.0.4
Cluster mcastPort 45564 45564
tcpListenAddress 192.168.0.10 192.168.0.20
tcpListenPort 4001 4002
Cache properties file jbosscache-config.xml jbosscache-config.xml
properties file location node1/CachingAOP/WEB-INF/config node2/CachingAOP/WEB-INF/config
Cache mcast_addr 228.1.2.3 228.1.2.3
Cache mcast_port 48866 48866
Cache bind_addr 192.168.0.10 192.168.0.20
Cache bind_port 9080 10080
Database c:/dev/db/loandb c:/dev/db/loandb

Instrumentation Layer

Two aspects called Trace and CacheLog were created to introduce logging and tracing capabilities into the web application to measure response times for accessing cached objects and to log various events in the caching process.

Tracing aspect was used to monitor the effectiveness of caching by calculating the total time taken to get the data (from the database or from cache). It takes longer when the data is accessed for the first time since the data is not in cache and we need to retrieve it from the back-end database. But subsequent calls are faster since data is already present in cache and no need to access the database. This aspect also measures the available JVM memory before and after each call to getInterestRates method.

Logging aspect was used to verify that the data is retrieved from a data source the first time it's requested by the client and from cache for all the subsequent requests. It was also used to keep track of cache hits and misses. All the log messages were saved in a single log file (cachingapp.log) to monitor the cache statistics and cluster details to see how many cluster members are alive and how cache changes (if any) are propagated between the cluster nodes.

Testing setup

To test the implementation of caching aspect and replication of cache changes, I wrote a test client called LoanAppClient. It uses the Commons HttpClient API to simulate the web request calls to LoanAppServlet to process loan applications. Based on a random number generated, the test client issues a different loan request (such as getting interest rates for either mortgage loans or HELOC loans). Depending on the request attributes sent to the server, LoanAppServlet gets the interest rate data for the specified loan type and product.

The hardware/software specifications of the PC used to test the sample web application are listed below.

  • CPU: HP Pavilion Pentium III 800 MHz
  • Memory: 512 MB RAM
  • Hard disk: 40 GB
  • Operating system: Windows 2000 server Service Pack 4
  • JDK version: 1.4.2_05
  • Tomcat version: 5.0.28
  • Tools Used: Tomcat, JBossCache, OSCache, HSQL DB, Eclipse, AspectJ, AJDT, Commons HttpClient

Listed below are the run-time parameters for LoanAppClient:

  • Number of client threads: 2
  • Number of repetitions: 1,000
  • Delay between requests: 1,000 milliseconds
  • Number of test samples: 1,000

The command used to run the test client with the required arguments is as follows:

java -Dlog4j.configuration=log4j.xml com.loanapp.test.LoanAppClient 1 192.168.0.10 9080 192.168.0.20 10080 2 1000

Test Results

The results from the web application test runs are listed in the following table:

Data Access Calls Without Caching
(ms) With Caching
(ms)
First request 140 180
Subsequent requests (avg) 50 5

Conclusion

We looked at how fast the data access can be when we use a cache to store frequently accessed objects. Even though it took little longer to get the interest rates data the first time from the database, it took almost no time to get data from cache compared to the time it took to get it from the database (5 milliseconds with caching compared to 50 milliseconds without caching). We also looked at how easy and flexible it is to make caching part of the web application by encapsulating caching logic in aspects.

One advantage of using aspects compared to traditional object oriented programming is that if something doesn't turn out to be as effective as originally expected, the aspect can be seamlessly un-weaved from the application code without any impact on the actual code. Aspects provide plug-n-play capabilities in the application development.

We have achieved the following design goals by implementing object caching as an aspect:

  • loosely coupled architecture.
  • separation of logic.
  • dynamic adaptation of caching and tracing cross-cutting concerns.
  • modularized design.

Currently, all the cache related code is written in the aspect files. This can be further refactored to separate cache logic into separate java classes and keep just the AOP related code (pointcuts, advices etc) in the aspect files. A good AOP system should involve collaboration between aspects that provide the key cross-cutting concerns and java classes that implement all the helper methods.

A JMX based Cache monitoring tool using aspect oriented design will be a good complementary tool to the CacheAOP framework described in this article. We can use this tool to monitor the effectiveness of caching by collecting the details such as hit/miss ratio, # of accesses, last access time, object size, time to load data from data source etc.

Appendix: Aspects

This section provides a brief overview of AOP. For more details on AOP and AspectJ topics, refer to AspectJ In Action book.

Aspect-oriented programming allows developers to add behavior to objects in a non-obtrusive, clean, and modularized manner through the use of static and dynamic crosscutting. The main goal of using aspects in application development is to code the cross-cutting concerns in separate modules and apply them in a flexible and declarative way. AOP is light weight compared to OOP in the sense that in OO frameworks we have to engineer utility functions and non-business related modules and we really can't completely separate these functions from the core application code, so they end up coupled together. But in AO programming we have the flexibility of achieving this goal of total separation of concerns.

Following are some of the advantages aspect oriented software development (AOSD) offers to complement J2EE application design, development, and deployment tasks:

  • Dynamic application of adaptations:
    Aspects are a great choice for implementing an autonomic system since we can apply code retrospectively to a running application without having to modify any of the existing application code.
  • Easy removal of adaptations:
    AOP frameworks allow easy removal of previously woven aspects returning the application code to its original state. Using AOP approach, it's very easy to remove previously introduced aspects by removing the advice attached to a particular join-point. Since the application code itself is not modified, we can safely rebuild and deploy the application without having to go through extensive unit testing and QA testing phases every time an aspect is removed from the application.
  • Encapsulation of Adaptations:
    AOP gives us the advantage of encapsulating the cross-cutting concerns such as caching, security, persistence, etc and thus provides the true separation of these modules from the core application resulting in greater reuse of code. The aspects are encapsulated meaning no external references or changes are required to the base application code. The same aspect could be introduced to any other application with only changes made to the pointcuts.
  • Specify inter-aspect relationships:
    We can specify relationships between the aspects themselves to achieve even more code reuse and flexibility.
  • Implement fine grained changes.
  • Apply adaptations to various points in a system:
    AOP models allow us to attach code to a wide variety of execution points, not just one place, in the program. This helps in avoiding writing the same code in multiple places in the application.

The various modules in a typical J2EE application that are good candidates for aspects are caching, pooling, logging, tracing, security, persistence, exception handling, unit testing using virtual mock objects, business rules, state management, and async/sync communication.

Other applications of aspects are database, operating systems, and J2EE design patterns. Awais Rashid, in his presentation on Aspect-Oriented Programming for Database Systems, discusses the cross-cutting concerns in Object Oriented Database (OODB) systems such as keeping persistent and transient space consistent, version management policy and locking scheme. Kiczales and others explain using AOP to improve operating system structure by implementing a prefetching aspect in Structuring Operating Systems Aspects.

The other area of using aspects is the design patterns. In the book Aspect-Oriented Software Development there is a discussion about aspect oriented alternatives to popular design patterns such as Visitor, Observer etc. Also, Russ Miles in his book AspectJ Cookbook talks about implementing creational object-oriented design patterns including Singleton, Prototype, Abstract Factory, Factory Method, and Builder patterns using AOP techniques.

The main components of AOP are aspects, join points, pointcut, advice and introduction. Following are the brief description of these AOP components:

Aspect:
Aspects are similar to java classes; they are units of modularity for cross-cutting concerns. Aspects define pointcuts and advices to dynamically weave cross-cutting concerns (such as logging, tracing, security etc) into existing objects in the program.

Join-Points:
These are well-defined points of execution in a program. Examples of joinpoints include calls to a method in a class, access to class members, conditional checks, variable assignments, and exception handler blocks. Join points have the context of target object and its arguments associated with them. A join point can sometimes contain other join points.

An example of join point is the call to method contextInitialized in LoanAppContextListener class in our sample web application. Join point is an abstract notion meaning we don't really define a join point in an aspect.

Point-Cut:
A pointcut is a program construct to capture join points and apply the cross-cutting concern. We defined a pointcut called contextInitialized in ObjectCache aspect in the sample web application.

Point-Cut Example:

    abstract pointcut contextInitialized(ServletContextEvent event);
          

Advice:
An advice is an additional block of code that we want to execute at specific points (pointcuts) in the program flow. There are different ways to associate an advice with a joinpoint: before (the advice runs just before the joinpoint), after (advice runs just after the joinpoint; after normal return or after throwing an exception in the method) and around (advice surrounds the joinpoint and we have the control when joinpoint execution proceeds) the execution of a joinpoint.

In our sample application, we define around advices for contextInitialized and contextDestroyed pointcuts. We also define before and after advices for calls to loan processor methods.

Advice Example:

    void around(ServletContextEvent event) : contextInitialized(event) {
       initObjectCache();
    }
          

Introduction:
Introduction allows us to add new state (attributes) and behavior (methods) to existing java classes without having to modify any code in the classes.

AOP: Static and Dynamic

AOP languages can be either static or dynamic based on the way an aspect is weaved into the application code. A static AOP language uses build-time weaving of aspects into the application. AspectJ framework is a popular example of static AOP implementation. AspectJ language is used in writing the aspects in the sample web application described in this article.

On the other hand, dynamic AOP languages offer the advantage of dynamically (at run-time) weaving the aspects and allow the application's behavior to be modified while the application is still running. Even though dynamic AOP provides a powerful tool to manipulate the application characteristics at run-time, it does have some disadvantages. The disadvantages of dynamic AOP approach are the performance hit taken to check whether or not an aspect should be woven at the current point of execution. There could also be some issues related to safety, security and compatibility when introducing additional code at run-time.

There are currently many dynamic AOP frameworks available. Some of the examples of dynamic AOP implementations are AspectWerkz, Java Aspect Components (JAC), Dynaop, Nanning, and Prose. Also, there are many J2EE application servers and frameworks that are using AOP concepts. JBoss Application Server and Spring framework are two examples of AOP implementations.

AspectJ and AJDT

AspectJ is an aspect oriented extension of Java language that enables creating aspects and integrating them into existing or new java applications. We can write aspects in the same way as we write the java classes with some new key words provided by AspectJ. Both an aspect and a java class have the same constructs so we can easily integrate them together without having to use different syntax and tools when we work with these two languages. AspectJ Development Tools for Eclipse (AJDT) is an Eclipse plugin that provides the tools to develop, build, and deploy J2EE applications using Java and AspectJ languages.

Resources


Author Bio

Srini Penchikala presently works as Information Systems Subject Matter Expert at Flagstar Bank. His IT career spans over 9 years with systems architecture, design, and development experience in client/server and Internet applications. Srini holds a master's degree from Southern Illinois University, Edwardsville and a bachelor's degree (Sri Venkateswara University, India) in Engineering. His main interests include researching new J2EE technologies and frameworks related to Web Portals. He has also contributed to ONJava, DevX Java and JavaWorld online journals. Srini's spare time is filled with spending time with his wife Kavitha and 3-month old daughter Srihasa and watching Detroit sports teams. Go Pistons.

分享到:
评论

相关推荐

    spring,spring-aop-5.3.22.jar+aop+IDEA本地包

    spring-aop-5.3.22.jar Spring AOP provides an Alliance-compliant aspect-oriented programming implementation allowing you to define method interceptors and pointcuts to cleanly decouple code that ...

    反射实现 AOP 动态代理模式(Spring AOP 的实现 原理) - Java 例子 -

    在Java编程中,AOP(面向切面编程)是一种强大的设计模式,它允许开发者将关注点分离,将横切关注点(如日志、事务管理)与核心业务逻辑解耦。Spring框架是Java中实现AOP的一个流行工具,它通过动态代理机制实现了这...

    aop思想的java实现

    **AOP思想与Java实现** 面向切面编程(Aspect-Oriented Programming,简称AOP)是一种编程范式,它旨在解决传统面向对象编程中的横切关注点,如日志、事务管理、性能监控等,这些关注点往往分散在程序的各个角落,...

    用Java动态代理实现AOP

    Java动态代理实现AOP Java动态代理是实现Aspect Oriented Programming(AOP)的重要手段。在Java中,动态代理可以通过java.lang.reflect InvocationHandler接口和java.lang.reflect.Proxy类来实现。AOP的主要思想...

    用java自己实现的动态代理 AOP

    Java动态代理是Java编程中一个重要的特性,它允许在运行时创建代理对象,这些代理对象可以作为原有对象的代理,实现在调用原有方法前后添加额外的功能,这正是AOP(面向切面编程)的核心思想。下面我们将深入探讨...

    Java JDK 实现AOP

    ### Java JDK 实现AOP详解 #### AOP的起源与发展 面向方面编程(Aspect-Oriented Programming,简称AOP)是一种编程范式,由施乐公司帕洛阿尔托研究中心(Xerox PARC)在20世纪90年代发明。AOP的初衷是为了更好地...

    java反射与代理实现AOP

    ### Java反射与代理实现AOP #### 一、AOP概念及应用场景 AOP(Aspect-Oriented Programming,面向切面编程)是一种编程思想和技术,主要用于处理横切关注点问题,比如日志记录、性能统计、安全控制、事务处理、...

    an_introduction_to_object-oriented_programming_with_java

    这本书《an_introduction_to_object-oriented_programming_with_java》非常适合作为学习Java面向对象编程的入门书籍。它由C.Thomas Wu编写,是面向对象编程教学的一个非常受欢迎的资源。书中内容全面,覆盖了面向...

    java动态代理实例aop

    2. 使用`Proxy.newProxyInstance()`方法创建代理对象,需要提供类加载器、目标接口数组以及自定义的`InvocationHandler`实例。 例如: ```java InvocationHandler handler = new MyInvocationHandler(target); ...

    spring aop 实现源代码--xml and annotation(带lib包)

    在Spring1.2或之前的版本中,实现AOP的传统方式就是通过实现Spring的AOP API来定义Advice,并设置代理对象。Spring根据Adivce加入到业务流程的时机的不同,提供了四种不同的Advice:Before Advice、After Advice、...

    java 实现AOP

     为了简单起见,例子没有没有使用任何第三方的AOP Framework, 而是利用Java语言本身自带的动态代理功能来实现AOP.  让我们先回到AOP本身,AOP主要应用于日志记录,性能统计,安全控制,事务处理等方面。它的主要...

    java 动态代理实现AOP

    ### Java动态代理实现AOP详解 #### 一、引言 随着软件开发复杂度的提升,传统的面向对象编程(OOP)已经...总之,通过本篇文章的学习,读者应该能够理解和掌握如何使用Java动态代理来实现AOP的基本原理及实践操作。

    Java面向对象程序设计-并发(实现Runnable接口).pptx

    Java面向对象程序设计-并发(实现Runnable接口) Java面向对象程序设计-并发(实现Runnable接口)是Java编程语言中的一种重要概念,它们都是农业信息系统开发的基础组件。下面我们将详细探讨Java面向对象程序设计-...

    Mybatis-plus基于redis实现二级缓存过程解析

    Mybatis-plus基于Redis实现二级缓存过程解析 Mybatis-plus是一款基于Java语言的持久层框架,旨在简化数据库交互操作。然而,在高并发、高性能的应用场景中,数据库的查询操作可能会成为性能瓶颈。为了解决这个问题...

    SHA-256-Matlab-Implements SHA-256 Algorithm.zip

    这个压缩包"SHA-256-Matlab-Implements SHA-256 Algorithm.zip"包含了相关的MATLAB代码,用于实现SHA-256算法。 SHA-256算法的工作原理是将任意长度的输入(也称为预映射)通过一系列复杂的数学和逻辑运算,转换成...

    python代码实现飞机大战The-Python-code-implements-aircraft-warfare.zi.zip

    【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、...

Global site tag (gtag.js) - Google Analytics