Spring标签@Aspect-实现面向方向编程(@Aspect的多数据源自动加载)——SKY
从Spring 2.0开始,可以使用基于schema及@AspectJ的方式来实现AOP。由于@Aspect是基于注解的,因此要求支持注解的5.0版本以上的JDK。
环境要求:
1. mybits的DB连接,实现动态多数据源的设置。
2. service层实现数据访问。
我们的目标是,如果用户调用Service层中任一方法,都配置其动态数据源Id。
在此先来说一下AOP:
AOP(Aspect-OrientedProgramming,面向方面编程),可以说是OOP(Object-Oriented Programing,面向对象编程)的补充和完善。OOP引入封装、继承和多态性等概念来建立一种对象层次结构,用以模拟公共行为的一个集合。当我们需要为分散的对象引入公共行为的时候,OOP则显得无能为力。也就是说,OOP允许你定义从上到下的关系,但并不适合定义从左到右的关系。例如日志功能。日志代码往往水平地散布在所有对象层次中,而与它所散布到的对象的核心功能毫无关系。对于其他类型的代码,如安全性、异常处理和透明的持续性也是如此。这种散布在各处的无关的代码被称为横切(cross-cutting)代码,在OOP设计中,它导致了大量代码的重复,而不利于各个模块的重用。
简介
前段时间写的java设计模式--代理模式,最近在看Spring Aop的时候,觉得于代理模式应该有密切的联系,于是决定了解下Spring Aop的实现原理。
说起AOP就不得不说下OOP了,OOP中引入封装、继承和多态性等概念来建立一种对象层次结构,用以模拟公共行为的一个集合。但是,如果我们需要为部分对象引入公共部分的时候,OOP就会引入大量重复的代码。例如:日志功能。
AOP技术利用一种称为“横切”的技术,解剖封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,这样就能减少系统的重复代码,降低模块间的耦合度,并有利于未来的可操作性和可维护性。AOP把软件系统分为两个部分:核心关注点和横切关注点。业务处理的主要流程是核心关注点,与之关系不大的部分是横切关注点。横切关注点的一个特点是,他们经常发生在核心关注点的多处,而各处都基本相似。比如权限认证、日志、事务处理。
下面说说@aspect实现的动态数据源配置:
1.定义一个Aspect。
必须使用@Aspect在类名之前注解。
当用户调用com.accessor.service包中任一类的任一方法,在调用前,Spring将自动执行下面的doBefore()方法,以及Doafter()方法。
这里数据源的选择是通过枚举实现的。
/**
* Created by Administrator on 2016/11/3.
*/
@Component
@Aspect
public class MultipleDataSourceAspect{
private static AtomicInteger counter = new AtomicInteger(0); @Before("execution(* com.accessor.service..*(..))")
public void doBefore(JoinPoint joinPoint) throws Throwable {
String className = joinPoint.getTarget().getClass().getName();
if (className.contains("oracle")) {
DataSourceContextHolder.setDataSourceType(DataSourceEnum.ORACLE_READ.getValue());
} else if (className.contains("sqlserver")) {
setMsDataSource(joinPoint.getArgs());
}
System.out.println("------------------begin"+counter.getAndIncrement() +"-----" + DataSourceContextHolder.getDataSourceType() + "--------thread:" + Thread.currentThread().getName()) ;
}
@After("execution(* com.accessor.service..*(..))")
public void doAfter(JoinPoint joinPoint) throws Throwable {
Object[] args = joinPoint.getArgs();
if (args != null && args.length > 0) {
if (args[0] instanceof Map) {
Map param = (Map) args[0];
param.remove("msHisFlag");
param.remove("tabNameSuffix");
}
}
System.out.println("--------------------end------------------remove:" + DataSourceContextHolder.getDataSourceType());
DataSourceContextHolder.clearDataSourceType();
} //设置ms数据源
private void setMsDataSource(Object[] args) {
DataSourceEnum dataSourceEnum = null;
if (args != null && args.length > 0) {
if (args[0] instanceof Map) {
Map param = (Map) args[0];
String fundId = CommonUtil.convert(param.get("fundId"), String.class);
if (fundId != null) {
if ("1".equals(param.get("msHisFlag"))) {
String tabNameSuffix = DateUtil.dateToStr(new Date(), "_yyyy_MM");
param.put("tabNameSuffix", tabNameSuffix);
dataSourceEnum = CommonUtil.getMsDataSourceEnum(fundId, true);
} else {
dataSourceEnum = CommonUtil.getMsDataSourceEnum(fundId);
}
}
DataSourceContextHolder.setDataSourceType(dataSourceEnum.getValue());
}
} if (dataSourceEnum == null) {
throw new RuntimeException("无法确定查询的sqlserver数据源");
}
}
}
2.spring的文件配置
<?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:context="http://www.springframework.org/schema/context" xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.1.xsd"> <!-- 自动扫描(自动注入) -->
<context:annotation-config/>
<context:component-scan base-package="com.eastmoney"/>
<aop:aspectj-autoproxy proxy-target-class="true"/> <bean id="springContextUtil " class="com.eastmoney.accessor.util.SpringContextUtil"/> <!-- 引入mybatis属性配置文件 -->
<import resource="spring-mybatis.xml"/>
</beans>
3.mybatis的文件配置
<?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:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <!-- 动态数据源 -->
<bean id="dataSource" class="com.eastmoney.accessor.datasource.DynamicDataSource">
<property name="dsConfigFile" value="dataSource.xml"/>
</bean> <!-- mybatis配置 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="mapperLocations" value="classpath*:mapper/*/*.xml"/>
<property name="configLocation" value="classpath:/mybatis-config.xml"/>
</bean> <!-- 自动创建映射器,不用单独为每个 mapper映射-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.eastmoney.accessor.mapper"/>
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
</bean> <!-- 事务管理器配置,单数据源事务 -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean> <tx:annotation-driven transaction-manager="transactionManager"/> </beans>
就这么简单而强大的Spring注解配置,非常感兴趣,下次去过一遍Spring的原理和注解的使用规则,有机会在和大家分享。
笔者:SKY-yong 2016/11/18
Spring标签@Aspect-实现面向方向编程(@Aspect的多数据源自动加载)——SKY的更多相关文章
- 【PHP面向对象(OOP)编程入门教程】23.自动加载类 __autoload()函数
很多开发者写面向对象的应用程序时,对每个类的定义建立一个 PHP 源文件.一个很大的烦恼是不得不在每个脚本(每个类一个文件)开头写一个长长的包含文件的列表. 在软件开发的系统中,不可能把所有的类都写在 ...
- 说明反转控制(IOC)和面向方向编程(AOP)在spring中的应用
说明反转控制(IOC)和面向方向编程(AOP)在spring中的应用 解答:Spring 核心容器(Core)提供Spring框架的基本功能.核心容器的主要组件是BeanFactory,它是工厂模式的 ...
- Spring boot 国际化自动加载资源文件问题
Spring boot 国际化自动加载资源文件问题 最近在做基于Spring boot配置的项目.中间遇到一个国际化资源加载的问题,正常来说只要在application.properties文件中定义 ...
- spring的applicationContext.xml如何自动加载
一个web工程自动加载的配置文件只有web.xml,想要加载其他.xml必须在web.xml里面进行配置. 用spring的时候需要一个bean容器来管理所有的bean,所有bean默认是写在appl ...
- ssh整合思想初步 struts2与Spring的整合 struts2-spring-plugin-2.3.4.1.jar下载地址 自动加载Spring中的XML配置文件 Struts2下载地址
首先需要JAR包 Spring整合Structs2的JAR包 struts2-spring-plugin-2.3.4.1.jar 下载地址 链接: https://pan.baidu.com/s/1o ...
- 面向切面编程 ( Aspect Oriented Programming with Spring )
Aspect Oriented Programming with Spring 1. 简介 AOP是与OOP不同的一种程序结构.在OOP编程中,模块的单位是class(类):然而,在AOP编程中模块的 ...
- Spring学习笔记:面向切面编程AOP(Aspect Oriented Programming)
一.面向切面编程AOP 目标:让我们可以“专心做事”,避免繁杂重复的功能编码 原理:将复杂的需求分解出不同方面,将公共功能集中解决 *****所谓面向切面编程,是一种通过预编译方式和运行期动态代理实现 ...
- 关于spring.net的面向切面编程 (Aspect Oriented Programming with Spring.NET)-简介
本文翻译自Spring.NET官方文档Version 1.3.2. 受限于个人知识水平,有些地方翻译可能不准确,但是我还是希望我的这些微薄的努力能为他人提供帮助. 侵删. 简介 Aspect-Orie ...
- 关于spring.net的面向切面编程 (Aspect Oriented Programming with Spring.NET)-切入点(pointcut)API
本文翻译自Spring.NET官方文档Version 1.3.2. 受限于个人知识水平,有些地方翻译可能不准确,但是我还是希望我的这些微薄的努力能为他人提供帮助. 侵删. 让我们看看 Spring.N ...
随机推荐
- C++ 如何得到当前进程所占用的内存呢?【转】
使用SDK的PSAPI (Process Status Helper)中的BOOL GetProcessMemoryInfo( HANDLE Process, PPROCESS_MEMORY_COUN ...
- JavaWeb项目实现文件下载
File file = new File(path);// path是根据日志路径和文件名拼接出来的 String filename = file.getName();// 获取日志文件名称 Inpu ...
- ASP.NET MVC学习---(四)MVC初窥
前面三篇大幅度的介绍了EF框架 这并不是没有道理的 现在使用mvc开发一般都离不开ef 因为它们相结合可以为你带来完美的体验 当然 前面所描述的仅仅是ef框架的冰山一角 它是一门学问很深的功课 如果你 ...
- selenium的PageObject设计模式
PageObject设计模式1. Web自动化测试框架(WebTestFramework)是基于Selenium框架且采用PageObject设计模式进行二次开发形成的框架. 2. web测试时,建议 ...
- Shell 同时读取多个文件
现有两个文件 1.txt 2.txt,内容分别如下: [root@SHO-XXW-- readmulti]# .txt [root@SHO-XXW-- readmulti]# .txt a b c ...
- spring拦截器不拦截方法名原因
开发一个基于注解的登录拦截器,遇到拦截器只能拦截controller不能拦截到具体的方法名,这样拦截器就完全没用,经过仔细摸索,DefaultAnnotationHandlerMapping和Anno ...
- ES7新特性
Array.prototype.includes Array.prototype.includes用法都容易和简单.它是一个替代indexOf,开发人员用来检查数组中是否存在值,indexOf是一种尴 ...
- spring集成PHPRPC及使用
PHPRPC,它的商业版本是Hprose.这里仅记录其使用方法.其它相关内容可自行搜索. 对于开源的东西,建议大家看看其源码. 1.需要引入的jar包:phprpc_spring.jar,http:/ ...
- oc 把view添加到rootcontrollerview控制的view
在当前活跃的window 添加一个view [[[[[UIApplication sharedApplication] keyWindow] rootViewController] view] add ...
- Unhandled event loop exception No more handles 解决办法
1 http://stackoverflow.com/questions/9074189/unhandled-event-loop-exception-in-plugin-org-eclipse-ui ...