春の研究ノート(B)
これは、沈殿プロセスであり、おそらく最初のコンタクト春はこの時点では昨年、非常に開発し、その後、トレーニング、のJavaウェブ、直接学習SSMフレーム(サーブレットは何の学校ではないとき)との最初の接触に持っていました悪い学習習慣、「Zhaomaohuahu。」であります 何がこの研究の習慣は確かに行き過ぎではないだろう、どんな考えず、それは望んでいる方法に応じて、他の人を行います。今、私は疑問の多くを持って、これは何ですか?これはなぜでしょうか?もっと良い方法?だから、このノートのテーマは" これは何?"
1. AOP
1.1 AOPイントロダクション
AOPとは何か1.1.1
- ソフトウェア業界では、AOPを意味し、アスペクト指向プログラミングのための略語です:アスペクト指向プログラミングを、事前にコンパイラの方法で均一なメンテナンスプログラムの実行時に動的プロキシの実装によって技術を採用しています。AOPはOOP(オブジェクト指向プログラミング)継続されたスプリングフレームワークの重要な要素は、機能プログラミングヤンShengfan型である、ホットソフトウェアの開発です。AOPは、開発の効率を向上させつつ、ビジネス・ロジックは、プログラムの再利用性を向上させ、部品間の結合の程度を低減するようなビジネス・ロジックの各部分を分離するために使用することができます。
- AOPは、伝統的な縦連続反復符号化システムを置き換える横抽出機構をとら
- Classicアプリケーション:トランザクション管理、パフォーマンス監視、セキュリティチェック、キャッシュ、ログ、など
- 春AOPは純粋なJava実装を使用すると、特別なコンパイルプロセスを必要とせず、実行時にクラスローダは、プロキシを経由して目的のクラスを強化するために、コードに織り込ま
- AspectJのAOPフレームワークは、Javaベースの開始Spring2.0、アスペクトの導入のための春AOP支持体である、AspectJの横織りに設けられたコンパイルタイムコードで、専用のコンパイラを提供する、Java言語を拡張します
1.1.2 AOPの実装原理
- AOPのエージェントが実装され、基礎となるメカニズムを使用します。
- インタフェースおよび実装クラス:動的エージェントプロキシJDKの春。
- 実装クラス:バイトコード拡張を使用してCGLIB春。
1.1.2 AOPの用語
- ターゲットクラスをターゲット:エージェントクラスであることを。たとえば、次のようにUserServiceの
- ジョインポイント接続点:いわゆる接続ポイントは、これらの方法が傍受されてもよいしています。たとえば、次のすべてのメソッド
ポイントカットのエントリポイント:接続ポイントが強化されました。例えば:アドユーザー()
- アドバイス予告/強化、強化コード。たとえば、次のようにした後、前
- 織りウィービングすること:新しいプロキシオブジェクトのプロキシを作成するプロセスに観客をターゲットに強化アドバイスを適用することを指します。
- プロキシプロキシクラス
アスペクトセクション:結合ポイントカットアドバイス通知のエントリポイントと
ラインは特殊な表面です。
特定の表面組成として通知するためのエントリポイント、。
1.2マニュアル
1.2.1 JDK動的プロキシ
- JDKダイナミックプロキシは「デコレータ」のデザインパターンを簡略化します。前提を使用してください:インタフェースが存在しなければなりません
- 対象クラス:インターフェースと実装クラス
- アスペクトクラス:通知を格納するためのMyAspect
- ファクトリクラス:プロキシを生成するための準備工場
テスト
1.2.1.1ターゲットクラス
public interface UserService {
void addUser();
void updateUser();
void deleteUser();
}
クラスセクション1.2.1.2
public class MyAspect {
public void before(){
System.out.println("this is before");
}
public void after(){
System.out.println("this is after");
}
}
1.2.1.3工場
public class MyBeanFactory {
public static UserService createService(){
//1 目标类
final UserService userService = new UserServiceImpl();
//2 切面类
final MyAspect myAspect = new MyAspect();
/**
* 3 代理类:将目标类(切入点)和 切面类(通知) 结合 --> 切面
* Proxy.newProxyInstance
* 参数1:loader ,类加载器,动态代理类 运行时创建,任何类都需要类加载器将其加载到内存。
* 一般情况:当前类.class.getClassLoader();
* 目标类实例.getClass().get...
* 参数2:Class[] interfaces 代理类需要实现的所有接口
* 方式1:目标类实例.getClass().getInterfaces() ;注意:只能获得自己接口,不能获得父元素接口
* 方式2:new Class[]{UserService.class}
* 例如:jdbc 驱动 --> DriverManager 获得接口 Connection
* 参数3:InvocationHandler 处理类,接口,必须进行实现类,一般采用匿名内部
* 提供 invoke 方法,代理类的每一个方法执行时,都将调用一次invoke
* 参数31:Object proxy :代理对象
* 参数32:Method method : 代理对象当前执行的方法的描述对象(反射)
* 执行方法名:method.getName()
* 执行方法:method.invoke(对象,实际参数)
* 参数33:Object[] args :方法实际参数
*
*/
UserService proxService = (UserService) Proxy.newProxyInstance(
MyBeanFactory.class.getClassLoader(),
userService.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//前执行
myAspect.before();
//执行目标类的方法
Object obj = method.invoke(userService,args);
//后方法
myAspect.after();
return obj;
}
}
);
return proxService;
}
}
}
1.2.1.4 Testクラス
@Test
public void demo01(){
UserService userService = MyBeanFactory.createService();
userService.addUser();
userService.updateUser();
userService.deleteUser();
}
1.2.2 CGLIBバイトコードの強化
- ノーインタフェース、唯一の実装クラス
- CGLIBバイトコードそれによってターゲットクラスを高める、実行時にターゲットクラスのサブクラスを作成し、補強フレームを使用。
- インポートのjarパッケージ:
彼らのリーダーパケット(こちら):
コア:hibernate-distribution-3.6.10.Final \ libに\バイトコード\ CGLIB \ CGLIB-2.2.jar
依存:ストラット-2.3.15.3 \ APPS \ Struts2の -定尺\ WEB- INF \ libにするの\ ASM-3.3.jar
春core..jarつ以上のコンテンツを統合しました
1.2.2.1ファクトリクラス
public class MyBeanFactory {
public static UserService createService(){
//1 目标类
final UserService userService = new UserServiceImpl();
//2 切面类
final MyAspect myAspect = new MyAspect();
// 3.代理类 ,采用cglib ,底层创建目标类的子类
// 3.1 核心类
Enhancer enhancer = new Enhancer();
// 3.2 确定父类
enhancer.setSuperclass(userService.getClass());
/**
* 3.3 设置回调函数 , MethodInterceptor接口 等效 jdk InvocationHander接口
* intercept() 等效 jdk invoke()
* 参数1、参数2、参数3:以invoke一样
* 参数4:methodProxy 方法的代理
*/
enhancer.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
//前执行
myAspect.before();
//执行目标类方法
Object obj = method.invoke(userService,objects);
// * 执行代理类的父类,执行目标类(目标类和代理类 父子关系)
// methodProxy.invokeSuper(o,objects);
//后执行
myAspect.after();
return obj;
}
});
//3.4 创建代理
UserServiceImpl proxService = (UserServiceImpl) enhancer.create();
return proxService;
}
}
1.3 AOPアライアンスの通知タイプ
- AOPアライアンスの通知アドバイスorg.aopalliance.aop.Adviceを定義します
- ターゲットクラスのメソッドの通知スプリング接続点位置に応じたアドバイスは、5つのカテゴリーに分けることができます
- アドバイスorg.springframework.aop.MethodBeforeAdvice前
- 強化ターゲット実行メソッドの実装前に、
- アドバイスを帰国後org.springframework.aop.AfterReturningAdvice
- 特定の実施形態強調法を行った後
- アドバイスorg.aopalliance.intercept.MethodInterceptorアラウンド
- エグゼクティブの実施を強化するために、ターゲットメソッドの前と後
- 例外が通知をスローされますorg.springframework.aop.ThrowsAdvice
- 拡張メソッドの実装は、例外をスローした後、
- 通知org.springframework.aop.IntroductionInterceptorの紹介
- ターゲットクラスのいくつかの新しいメソッドとプロパティを追加します。
环绕通知,必须手动执行目标方法 try{ //前置通知 //执行目标方法 //后置通知 } catch(){ //抛出异常通知 }
1.4ばね剤を調製する:半自動
- アドバイスorg.springframework.aop.MethodBeforeAdvice前
- プロキシオブジェクト、手動で春のコンテナから取得したプロキシオブジェクトを作成するために、スプリングましょう。
- インポートジャーパッケージ:
コア:+ 1.4
AOP:AOPアライアンス(仕様)、スプリングAOP(実装)
1.4.1ターゲットクラス
public interface UserService {
void addUser();
void updateUser();
void deleteUser();
}
クラスセクション1.4.2
/**
* 切面类中确定通知,需要实现不同接口,接口就是规范,从而就确定方法名称。
* 采用“环绕通知” MethodInterceptor
*/
public class MyAspect implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation methodInvocation) throws Throwable {
System.out.println("this is before");
//手动执行目标方法
Object obj = methodInvocation.proceed();
System.out.println("this is after");
return obj;
}
}
1.4.3 Spring構成
<!-- 1 创建目标类-->
<bean id="userService" class="com.springlearning.spring_proxy.UserServiceImpl"></bean>
<!-- 2 创建切面类-->
<bean id="myAspect" class="com.springlearning.spring_proxy.MyAspect"></bean>
<!-- 3 创建代理类
* 使用工厂bean FactoryBean ,底层调用getObject() 返回特殊bean
* ProxyFactoryBean 用于创建代理工厂bean ,生成特殊代理对象
interfaces : 确定接口们
通过<array> 可以设置多个值
只有一个值时, value=""
target : 确定目标类
interceptorNames : 通知 切面类的名称,类型String[], 如果设置一个值 value=""
optimize :强制使用cglib
<property name="optimize" value="true"></property>
底层机制
如果目标类有接口,采用jdk动态代理
如果没有接口,采用cglib 字节码增强
如果声明 optimize = true ,无论是否有接口 ,都采用cglib
-->
<bean id="proxyService" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="interfaces" value="com.springlearning.spring_proxy.UserService"></property>
<property name="target" ref="userService"></property>
<property name="interceptorNames" value="myAspect"></property>
</bean>
1.4.4テスト
@Test
public void demo01(){
String xmlPath = "com/springlearning/spring_proxy/beans.xml";
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
//获得代理类
UserService userService = (UserService) applicationContext.getBean("proxyService");
userService.addUser();
userService.updateUser();
userService.deleteUser();
}
1.5スプリングAOPプログラミング:自動
- AOP構成、ばねが自動的にプロキシを生成する場合、ばね容器は、対象クラスから得られます。
- JARパッケージを導入し、対象クラス、AspectJのポイントカット式を決定するには
春-AOP-5.0.4バージョンでaopallianceとAspectJのが含まれています
aopallianceのスプリングAOP-5.0.4のバージョンに含まれている問題を、デバッグするときに私はここにいる、と私は、教育がバージョン3.x、追加aopallianceパッケージをインポートする必要があるだけでなく、間違いaspectjrtだと思いますaspectjweaverは、しかし、二つのパッケージは異なる機能を持っています。
1.5.1 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"
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">
<!-- 1 创建目标类 -->
<bean id="userService" class="com.springlearning.spring_proxy.UserServiceImpl"></bean>
<!-- 2 创建切面类(通知)-->
<bean id="myAspect" class="com.springlearning.spring_proxy.MyAspect"></bean>
<!-- 3 aop编程
3.1 导入命名空间
3.2 使用 <aop:config> 进行配置
proxy-target-class="true" 声明时使用cglib代理
<aop:pointcut> 切入点 , 从目标对象获得具体方法
<aop:advisor> 特殊的切面, 只用一个通知 和一个切入点
advice-ref 通知引用
pointcut-ref 切入点引用
3.3 切入点表达式
execution(* com.springlearning.spring_proxy.*.(..))
选择方法 返回值任意 包 类名称任意 方法名任意 参数任意
-->
<aop:config proxy-target-class="true">
<aop:pointcut id="myPointCut" expression="execution(* com.springlearning.spring_proxy.*.*(..))"/>
<aop:advisor advice-ref="myAspect" pointcut-ref="myPointCut"></aop:advisor>
</aop:config>
</beans>
1.5.2テスト
@Test
public void demo01(){
String xmlPath = "com/springlearning/spring_proxy/beans.xml";
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
//获得代理类
UserService userService = (UserService) applicationContext.getBean("userService");
userService.addUser();
userService.updateUser();
userService.deleteUser();
}
2. AspectJの
2.1はじめに
- AspectJのAOPフレームワークはJava言語に基づいています
- Spring2.0は、後のAspectJ表現ポイントカットのためのサポートを追加しました
- @AspectJ 是AspectJ1.5新增功能,通过JDK5注解技术,允许直接在Bean类中定义切面
新版本Spring框架,建议使用AspectJ方式来开发AOP - 主要用途:自定义开发
2.2 切入点表达式
- execution() 用于描述方法
语法:execution(修饰符 返回值 包.类.方法名(参数) throws异常)
修饰符,一般省略
public 公共方法
* 任意
返回值,不能省略
void 返回没有值
String 返回值字符串
* 任意
包,[省略]
com.springlearning.proxy 固定包
com.springlearning.proxy..service proxy包下面子包任意 (例如:com.springlearning.proxy.staff.service)
com.springlearning.proxy.. proxy包下面的所有子包(含自己)
com.springlearning.proxy..service.. proxy包下面任意子包,固定目录service,service目录任意包
类,[省略]
UserServiceImpl 指定类
Impl 以Impl结尾
User 以User开头
* 任意
方法名,不能省略
addUser 固定方法
add* 以add开头
Do 以Do结尾
任意
(参数)
() 无参
(int) 一个整型
(int ,int) 两个
(..) 参数任意
throws ,可省略,一般不写。
综合 1
execution(* com.springlearning.proxy..service...*(..))
综合 2
<aop:pointcut expression="execution(* com.springlearning.WithCommit.(..)) ||
execution(* com.springlearning.Service.(..))" id="myPointCut"/>
- within:匹配包或子包中的方法
within(com.springlearning.aop..*) - this:匹配实现接口的代理对象中的方法
this(com.springlearning.aop.user.UserDAO) - target:匹配实现接口的目标对象中的方法
target(com.springlearning.aop.user.UserDAO) - args:匹配参数格式符合标准的方法
args(int,int) - bean(id) 对指定的bean所有的方法(了解)
bean('userService')
2.3 AspectJ 通知类型
- aop联盟定义通知类型,具有特性接口,必须实现,从而确定方法名称。
- aspectj 通知类型,只定义类型名称。已经方法格式。
- 个数:6种,知道5种,掌握1中
before:前置通知(应用:各种校验)
在方法执行前执行,如果通知抛出异常,阻止方法运行
afterReturning:后置通知(应用:常规数据处理)
方法正常返回后执行,如果方法中抛出异常,通知无法执行
必须在方法执行后才执行,所以可以获得方法的返回值。
around:环绕通知(应用:十分强大,可以做任何事情)
方法执行前后分别执行,可以阻止方法的执行
必须手动执行目标方法
afterThrowing:抛出异常通知(应用:包装异常信息)
方法抛出异常后执行,如果方法没有抛出异常,无法执行
after:最终通知(应用:清理现场)
方法执行完毕后执行,无论方法中是否出现异常
环绕
try{
//前置:before
//手动执行目标方法
//后置:afterRetruning
} catch(){
//抛出异常 afterThrowing
} finally{
//最终 after
}
2.4 导入jar包
- 4个:
aop联盟规范
spring aop 实现
aspect 规范
spring aspect 实现
2.5 基于xml
- 目标类:接口 + 实现
- 切面类:编写多个通知,采用aspectj 通知名称任意(方法名任意)
- aop编程,将通知应用到目标类
- 测试
2.5.1 切面类
/**
* 切面类,含有多个通知
*/
public class MyAspect {
public void myBefore(JoinPoint joinPoint){
System.out.println("前置通知:" + joinPoint.getSignature().getName());
}
public void myAfterReturning(JoinPoint joinPoint,Object ret){
System.out.println("后置通知 : " + joinPoint.getSignature().getName() + " , -->" + ret);
}
public Object myAround(ProceedingJoinPoint joinPoint) throws Throwable{
System.out.println("前");
//手动执行目标方法
Object obj = joinPoint.proceed();
System.out.println("后");
return obj;
}
public void myAfterThrowing(JoinPoint joinPoint,Throwable throwable){
System.out.println("抛出异常通知:" + throwable.getMessage());
}
public void myAfter(JoinPoint joinPoint){
System.out.println("最终通知");
}
}
2.5.2 spring配置
<!-- 1 创建目标类 -->
<bean id="userService" class="com.springlearning.aspectj.UserServiceImpl"></bean>
<!-- 2 创建切面类(通知)-->
<bean id="myAspect" class="com.springlearning.aspectj.MyAspect"></bean>
<!-- 3 aop编程
<aop:aspect> 将切面类 声明“切面”,从而获得通知(方法)
ref 切面类引用
<aop:pointcut> 声明一个切入点,所有通知都可以使用。
expression 切入点表达式
id 名称,用于其他通知引用
-->
<aop:config>
<aop:aspect ref="myAspect">
<aop:pointcut id="myPointcut" expression="execution(* com.springlearning.aspectj.UserServiceImpl.*(..))"/>
<!-- 3.1 前置通知
<aop:before method="" pointcut="" pointcut-ref=""/>
method : 通知,及方法名
pointcut :切入点表达式,此表达式只能当前通知使用。
pointcut-ref : 切入点引用,可以与其他通知共享切入点。
通知方法格式:public void myBefore(JoinPoint joinPoint){
参数1:org.aspectj.lang.JoinPoint 用于描述连接点(目标方法),获得目标方法名等
例如:
<aop:before method="myBefore" pointcut-ref="myPointCut"/>
-->
<!-- 3.2后置通知 ,目标方法后执行,获得返回值
<aop:after-returning method="" pointcut-ref="" returning=""/>
returning 通知方法第二个参数的名称
通知方法格式:public void myAfterReturning(JoinPoint joinPoint,Object ret){
参数1:连接点描述
参数2:类型Object,参数名 returning="ret" 配置的
例如:
<aop:after-returning method="myAfterReturning" pointcut-ref="myPointCut" returning="ret" />
-->
<!-- 3.3 环绕通知
<aop:around method="" pointcut-ref=""/>
通知方法格式:public Object myAround(ProceedingJoinPoint joinPoint) throws Throwable{
返回值类型:Object
方法名:任意
参数:org.aspectj.lang.ProceedingJoinPoint
抛出异常
执行目标方法:Object obj = joinPoint.proceed();
例如:
<aop:around method="myAround" pointcut-ref="myPointCut"/>
-->
<!-- 3.4 抛出异常
<aop:after-throwing method="" pointcut-ref="" throwing=""/>
throwing :通知方法的第二个参数名称
通知方法格式:public void myAfterThrowing(JoinPoint joinPoint,Throwable e){
参数1:连接点描述对象
参数2:获得异常信息,类型Throwable ,参数名由throwing="e" 配置
例如:
<aop:after-throwing method="myAfterThrowing" pointcut-ref="myPointCut" throwing="e"/>
-->
<!-- 3.5 最终通知-->
<aop:after method="myAfter" pointcut-ref="myPointcut"></aop:after>
</aop:aspect>
</aop:config>
2.6 基于注解
2.6.1 替换bean
<!-- 1 创建目标类 -->
<bean id="userService" class="com.springlearning.aspectj.UserServiceImpl"></bean>
<!-- 2 创建切面类(通知)-->
<bean id="myAspect" class="com.springlearning.aspectj.MyAspect"></bean>
@Component
public class MyAspect {
@Service("userService")
public class UserServiceImpl implements UserService {
- 注意:扫描
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
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
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 1. 扫描 注解类 -->
<context:component-scan base-package="com.springlearning.aspectj"></context:component-scan>
2.6.2 替换 aop
- 必须进行aspectj 自动代理
<!-- 2.确定 aop注解生效 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
- 声明切面
<aop:aspect ref="myAspect"> <!--被下面注解替换 -->
@Component
@Aspect //添加注解
public class MyAspect {
- 替换前置通知
<aop:before method="myBefore" pointcut="execution(* com.ithspringlearning.aspectj.UserServiceImpl.*(..))"/> <!--被下面注解替换 -->
//切入点当前有效
@Before("execution(* com.springlearning.aspectj.UserServiceImpl.*(..))")
public void myBefore(JoinPoint joinPoint){
System.out.println("前置通知:" + joinPoint.getSignature().getName());
}
- 替换 公共切入点
<aop:pointcut id="myPointcut" expression="execution(* com.springlearning.aspectj.UserServiceImpl.*(..))"/>
<!--被下面注解替换 -->
//声明公共切入点
@Pointcut("execution(* com.springlearning.aspectj.UserServiceImpl.*(..))")
private void myPointCut(){}
- 替换后置
<aop:after-returning method="myAfterReturning" pointcut-ref="myPointCut" returning="ret" />
@AfterReturning(value = "myPointCut()",returning = "ret")
public void myAfterReturning(JoinPoint joinPoint,Object ret){
System.out.println("后置通知 : " + joinPoint.getSignature().getName() + " , -->" + ret);
}
- 环绕替换
<aop:around method="myAround" pointcut-ref="myPointCut"/>
@Around(value = "myPointCut()")
public Object myAround(ProceedingJoinPoint joinPoint) throws Throwable{
System.out.println("前");
//手动执行目标方法
Object obj = joinPoint.proceed();
System.out.println("后");
return obj;
}
- 替换抛出异常
<aop:after-throwing method="myAfterThrowing" pointcut-ref="myPointCut" throwing="throwable"/>
@AfterThrowing(value = "myPointCut()" ,throwing = "throwable")
public void myAfterThrowing(JoinPoint joinPoint,Throwable throwable){
System.out.println("抛出异常通知:" + throwable.getMessage());
}
2.6.3 切面类
/**
* 切面类,含有多个通知
*/
@Component
@Aspect
public class MyAspect {
//声明公共切入点
@Pointcut("execution(* com.springlearning.aspectj.UserServiceImpl.*(..))")
private void myPointCut(){}
// @AfterReturning(value = "myPointCut()",returning = "ret")
public void myAfterReturning(JoinPoint joinPoint,Object ret){
System.out.println("后置通知 : " + joinPoint.getSignature().getName() + " , -->" + ret);
}
//切入点当前有效
// @Before("execution(* com.springlearning.aspectj.UserServiceImpl.*(..))")
public void myBefore(JoinPoint joinPoint){
System.out.println("前置通知:" + joinPoint.getSignature().getName());
}
// @Around(value = "myPointCut()")
public Object myAround(ProceedingJoinPoint joinPoint) throws Throwable{
System.out.println("前");
//手动执行目标方法
Object obj = joinPoint.proceed();
System.out.println("后");
return obj;
}
// @AfterThrowing(value = "myPointCut()" ,throwing = "throwable")
public void myAfterThrowing(JoinPoint joinPoint,Throwable throwable){
System.out.println("抛出异常通知:" + throwable.getMessage());
}
@After(value = "myPointCut()")
public void myAfter(JoinPoint joinPoint){
System.out.println("最终通知");
}
}
2.6.4 spring 配置
<!-- 1. 扫描 注解类 -->
<context:component-scan base-package="com.springlearning.aspectj"></context:component-scan>
<!-- 2.确定 aop注解生效 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
2.6.5 aop 注解总结
- 通知されるように切断されたクラスを変更@Aspectステートメントセクション、。
- お知らせ
- フロント@Before
- @AfterReturning后置
- @Aroundサラウンド
- スロー@AfterThrowing
- 最終@After
- エントリー・ポイント
- @PointCut、修飾方法プライベートボイドXXX(){}「メソッド名」を参照することによって得られた出発点後
3. JdbcTemplate
- DBUtils:同様のツールを動作させるために提供JDBCスプリング。
- データソースに依存する接続プール(データ・ソース)
構築するために3.1環境
3.1.1テーブルを作成します。
create table t_user(
id int primary key ,
username varchar(50),
password varchar(32)
);
3.1.2インポートジャーパッケージ
3.1.3たjavaBean
public class User {
private Integer id;
private String username;
private String password;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
3.2 API
@Test
public void demo(){
//1 创建数据源(连接池) dbcp
BasicDataSource dataSource = new BasicDataSource();
// * 基本4项
dataSource.setDriverClassName("oracle.jdbc.driver.OracleDriver");
dataSource.setUrl("jdbc:oracle:thin:@localhost:1530/orcl");
dataSource.setUsername("sys as sysdba");
dataSource.setPassword("sys");
//2 创建模板
JdbcTemplate jdbcTemplate = new JdbcTemplate();
jdbcTemplate.setDataSource(dataSource);
//3 通过api操作
jdbcTemplate.update("insert into t_user(id,username,password) values(?,?,?)","6", "tom","998");
}
3.3 DBCP
<!-- 创建数据源 -->
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"></property>
<property name="url" value="jdbc:oracle:thin:@localhost:1530/orcl"></property>
<property name="username" value="sys as sysdba"></property>
<property name="password" value="sys"></property>
</bean>
<!-- 创建模板 ,需要注入数据源-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 配置dao -->
<bean id="userDao" class="com.springlearning.jdbctemplate.UserDao">
<property name="jdbcTemplate" ref="jdbcTemplate"></property>
</bean>
3.4設定C3P0
<!-- 创建C3P0数据源 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="oracle.jdbc.driver.OracleDriver"></property>
<property name="jdbcUrl" value="jdbc:oracle:thin:@localhost:1530/orcl"></property>
<property name="user" value="sys as sysdba"></property>
<property name="password" value="sys"></property>
</bean>
- ここでのjarパッケージのバージョンC3P0で注意mchange-コモンズ-のjava-0.2.3が必要です。システムの起動時に補助パッケージC3P0データベース接続プールされたパッケージは、これが利用できないc3p0-0.9.2でClassNotFoundExceptionが、報告されますパッケージのバージョンを分離した後、0.9.1、またはときのパッケージを取得します
3.5使用JdbcDaoSupport
3.5.1 dao层
package com.springlearning.jdbctemplate;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import java.util.List;
/**
* @ClassName:UserDao
* @author: donkey-boy
* @date:2019/7/19 10:52
*/
public class UserDao extends JdbcDaoSupport {
/**
* @Author: donkey-boy
* @Description: 更新操作
* @Param: user
* @Return: void
* @Date: 2019/7/19 15:04
*/
public void update(User user){
String sql = "UPDATE t_user SET username=?,password=? WHERE id=?";
Object[] args = {user.getUsername(),user.getPassword(),user.getId()};
this.getJdbcTemplate().update(sql,args);
}
/**
* @Author: donkey-boy
* @Description: 查询全部
* @Param: []
* @Return: java.util.List<com.springlearning.jdbctemplate.User>
* @Date: 2019/7/19 15:06
*/
public List<User> findAll(){
List<User> userList = this.getJdbcTemplate().query("select * from t_user", BeanPropertyRowMapper.newInstance(User.class));
return userList;
}
/**
* @Author: donkey-boy
* @Description: 获取单个用户
* @Param: [id]
* @Return: com.springlearning.jdbctemplate.User
* @Date: 2019/7/19 15:06
*/
public User getUser(int id){
User user = this.getJdbcTemplate().queryForObject("select * from t_user where id=?", BeanPropertyRowMapper.newInstance(User.class), id);
return user;
}
}
3.5.2春プロファイル
<!-- 配置dao
* dao 继承 JdbcDaoSupport,之后只需要注入数据源,底层将自动创建模板
-->
<!-- 配置dao -->
<bean id="userDao" class="com.springlearning.jdbctemplate.UserDao">
<property name="dataSource" ref="dataSource"></property>
</bean>
3.5.3ソースコード解析
3.6構成プロパティ
3.6.1プロパティファイル
jdbc.driverClass=oracle.jdbc.driver.OracleDriver
jdbc.jdbcUrl=jdbc:oracle:thin:@localhost:1530/orcl
jdbc.user=sys as sysdba
jdbc.password=sys
3.6.2 Spring構成
<!-- 加载配置文件
"classpath:"前缀表示 src下
在配置文件之后通过 ${key} 获得内容
-->
<context:property-placeholder location="classpath:com/springlearning/jdbctemplate/jdbcInfo.properties"></context:property-placeholder>
<!-- 创建C3P0数据源 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driverClass}"></property>
<property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
<property name="user" value="${jdbc.user}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
教育春からチュアンカイポッドキャストノート