- 浏览: 214905 次
- 性别:
- 来自: 北京
最新评论
-
xupo:
tzg157 写道qinkangwencai 写道别误导大家了 ...
Java多线程编程环境中单例模式的实现 -
xupo:
qinkangwencai 写道别误导大家了行吗?double ...
Java多线程编程环境中单例模式的实现 -
qaddafi2008:
内部静态类的方法貌似是目前最好的解法了!
Java多线程编程环境中单例模式的实现 -
sanshizi:
学习了
Java多线程编程环境中单例模式的实现 -
tzg157:
qinkangwencai 写道别误导大家了行吗?double ...
Java多线程编程环境中单例模式的实现
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:
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:
- Avoid duplicating the caching logic at every execution point in the application where there is a business case for data caching.
- 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.
- 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.
- 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.
- 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.
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:
- Run the web application with no caching implemented.
- Caching is implemented using JBossCache.
- 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.
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:
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.
|
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.
发表评论
-
RHEL5 利用 CentOS的yum 安装openssl gc++及Nginx
2011-04-12 16:17 122261.确保RHEL5中已经安装了yum[root@xupo~]# ... -
用URL重写来实现会话管理
2011-04-11 11:02 1327通常,会话管理是通过服务器将 Session ID 作为一个 ... -
JAVA实现与Linux通信(通过SSH协议)
2011-03-24 14:47 5786使用InputStream和OutputStream来获得命令 ... -
花生壳配置
2011-03-18 17:22 1030[edgen@rhel54 ~]$ su - root口令:[ ... -
服务器相关配置备忘
2011-03-11 10:28 1290JDK安装配置 1、下载jd ... -
Hibernate C3P0 Maven 配置
2011-02-10 14:55 2999pom.xml中增加: <depe ... -
用blazeDS实现推技术
2010-11-11 10:37 1118http://blog.csdn.net/yangyawen/ ... -
用 Quartz 进行作业调度
2010-09-06 14:46 940http://www.ibm.com/developerwor ... -
工作流
2010-09-06 14:26 1050jbpm4 :http://sourceforge.net/p ... -
《构建高性能web站点》读书笔记
2010-08-13 20:20 1056《构建高性能web站点》读书笔记 http://book.g ... -
Comet:基于 HTTP 长连接的“服务器推”技术
2010-08-13 20:15 887http://czh19860925.iteye.com/bl ... -
(转)关于大型软件重构的一些想法
2010-04-01 20:51 1142做当前这个项目也快 ... -
关于设计模式中各种工厂的理解
2010-04-01 20:46 1062对于Java的工厂模式,简单工厂、工厂方法、抽象工厂之间的区别 ... -
(转)探讨代理模式与Java反射机制的应用
2010-04-01 20:21 1337代理模式,相信大多数人都非常熟悉,常见的实现方式是通过公共接口 ... -
OpenNMS架构介绍
2010-03-30 10:06 12595一、OpenNMS简介 OpenNMS的开发基于TMN及FC ... -
OpenNMS配置指南
2010-03-30 09:54 3218OpenNMS的配置是一个繁琐的过程,由于网上没有系统介绍如何 ... -
java调用javascript :js引擎rhino
2009-10-30 16:04 9273前段时间,在浏览javaeye论坛,看见有人征集如何在java ... -
扩展 Eclipse 辅助和规范开发流程
2009-10-26 15:12 1482本如果市场上的开发工具不能满足您的需要,而自己开发 IDE 又 ... -
How to access eclipse workspace?
2009-10-26 14:36 1352摘要: 在开发eclipse pluin的时候,某些情况下 ... -
作业调度器的JAVA实现(第一篇)--Job Scheduling in Java
2009-09-07 23:41 2874On some projects, you find you ...
相关推荐
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 ...
在Java编程中,AOP(面向切面编程)是一种强大的设计模式,它允许开发者将关注点分离,将横切关注点(如日志、事务管理)与核心业务逻辑解耦。Spring框架是Java中实现AOP的一个流行工具,它通过动态代理机制实现了这...
**AOP思想与Java实现** 面向切面编程(Aspect-Oriented Programming,简称AOP)是一种编程范式,它旨在解决传统面向对象编程中的横切关注点,如日志、事务管理、性能监控等,这些关注点往往分散在程序的各个角落,...
Java动态代理实现AOP Java动态代理是实现Aspect Oriented Programming(AOP)的重要手段。在Java中,动态代理可以通过java.lang.reflect InvocationHandler接口和java.lang.reflect.Proxy类来实现。AOP的主要思想...
Java动态代理是Java编程中一个重要的特性,它允许在运行时创建代理对象,这些代理对象可以作为原有对象的代理,实现在调用原有方法前后添加额外的功能,这正是AOP(面向切面编程)的核心思想。下面我们将深入探讨...
### Java JDK 实现AOP详解 #### AOP的起源与发展 面向方面编程(Aspect-Oriented Programming,简称AOP)是一种编程范式,由施乐公司帕洛阿尔托研究中心(Xerox PARC)在20世纪90年代发明。AOP的初衷是为了更好地...
### Java反射与代理实现AOP #### 一、AOP概念及应用场景 AOP(Aspect-Oriented Programming,面向切面编程)是一种编程思想和技术,主要用于处理横切关注点问题,比如日志记录、性能统计、安全控制、事务处理、...
这本书《an_introduction_to_object-oriented_programming_with_java》非常适合作为学习Java面向对象编程的入门书籍。它由C.Thomas Wu编写,是面向对象编程教学的一个非常受欢迎的资源。书中内容全面,覆盖了面向...
2. 使用`Proxy.newProxyInstance()`方法创建代理对象,需要提供类加载器、目标接口数组以及自定义的`InvocationHandler`实例。 例如: ```java InvocationHandler handler = new MyInvocationHandler(target); ...
在Spring1.2或之前的版本中,实现AOP的传统方式就是通过实现Spring的AOP API来定义Advice,并设置代理对象。Spring根据Adivce加入到业务流程的时机的不同,提供了四种不同的Advice:Before Advice、After Advice、...
为了简单起见,例子没有没有使用任何第三方的AOP Framework, 而是利用Java语言本身自带的动态代理功能来实现AOP. 让我们先回到AOP本身,AOP主要应用于日志记录,性能统计,安全控制,事务处理等方面。它的主要...
### Java动态代理实现AOP详解 #### 一、引言 随着软件开发复杂度的提升,传统的面向对象编程(OOP)已经...总之,通过本篇文章的学习,读者应该能够理解和掌握如何使用Java动态代理来实现AOP的基本原理及实践操作。
Java面向对象程序设计-并发(实现Runnable接口) Java面向对象程序设计-并发(实现Runnable接口)是Java编程语言中的一种重要概念,它们都是农业信息系统开发的基础组件。下面我们将详细探讨Java面向对象程序设计-...
Mybatis-plus基于Redis实现二级缓存过程解析 Mybatis-plus是一款基于Java语言的持久层框架,旨在简化数据库交互操作。然而,在高并发、高性能的应用场景中,数据库的查询操作可能会成为性能瓶颈。为了解决这个问题...
这个压缩包"SHA-256-Matlab-Implements SHA-256 Algorithm.zip"包含了相关的MATLAB代码,用于实现SHA-256算法。 SHA-256算法的工作原理是将任意长度的输入(也称为预映射)通过一系列复杂的数学和逻辑运算,转换成...
【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、...