AOP: Aspect Oriented Programming 面向切面编程 是对OOP的补充
可以实现多继承
在应用AOP编程时,仍然需要定义公共的功能,但可以明确的定义这个功能在哪里,以什么方式应用,并且不必修改影响的类,
好处:每个事物逻辑位于一个位置,代码不分散,便于维护和升级
业务模块更简洁,只包含核心业务代码
切面(Aspect):横切关注点被模块化的特殊对象
通知(Advice):切面必须完成的工作
目标(Target):被通知的对象
代理(Proxy):向目标对象应用通知之后创建的对象
链接点(Joinpoint):程序执行的某个特定位置
切点:(pointcut)
@Component
在持久层、业务层和控制层分别采用 @Repository、@Service 和 @Controller 对分层中的类进行注释,而用 @Component 对那些比较中立的类进行注释
这里就是说把这个类交给Spring管理,重新起个名字叫userManager,由于不好说这个类属于哪个层面,就用@Component
代码:
核心Service
@Service
public
class
ArithmeticServiceImpl
implements
ArithmeticService {
@Override
public
int
add(
int
x
,
int
y
) {
//
TODO
Auto-generated method stub
int
result
=
x
+
y
;
return
result
;
}
@Override
public
int
sub(
int
x
,
int
y
) {
//
TODO
Auto-generated method stub
int
result
=
x
-
y
;
return
result
;
}
@Override
public
int
mul(
int
x
,
int
y
) {
//
TODO
Auto-generated method stub
int
result
=
x
*
y
;
return
result
;
}
@Override
public
int
div(
int
x
,
int
y
) {
//
TODO
Auto-generated method stub
int
result
=
x
/
y
;
return
result
;
}
切面AOP
@Component
//定义的是一个切面
@Aspect
public
class
LoggerAspect {
//前置通知
@Before
(value =
"execution(* com..*Service.*(..))"
)
public
void
before01(JoinPoint
joinPoint
){
System.
out
.println(
"接口实现类"
+
joinPoint
.getTarget().getClass().getName());
System.
out
.println(
"方法名称"
+
joinPoint
.getSignature().getName());
System.
out
.println(
"传递的参数"
+Arrays.
asList
(
joinPoint
.getArgs()));
}
//后置通知
@After
(value =
"execution(* com..*Service.*(..))"
)
public
void
after01(JoinPoint
joinPoint
){
System.
out
.println(
"@After实现类"
);
}
//异常通知
@AfterThrowing
(value =
"execution(* com..*Service.*(..))"
,throwing=
"shxtSpl"
)
public
void
Exception01(JoinPoint
joinPoint
,Exception
shxtSpl
){
System.
out
.println(
"@AfterThrowing"
);
}
//返回通知
@AfterReturning
(value =
"execution(* com..*Service.*(..))"
,returning=
"nihao"
)
public
void
returnAdvice(JoinPoint
joinPoint
,Object
nihao
){
System.
out
.println(
"@AfterReturning"
+
nihao
);
}
/**
* 第一个星是任意的返回类型
* 第二表示包的情况 只能一层
* .. 任意层
* *Service 以service结尾的
* 第四个代表的是该接口或当中的所有方法
* 第五个星参数任意类型
* ..任意
*/
/**
*
//@Around(value = "execution(
int
com
.*.*.ArithmeticService.add(*,*))")
//@Around(value = "execution(
int
com.shxt.service.ArithmeticService.add(
int
,
int
))")
//监控add或者
div
//@Around(value = "execution(
int
com
..ArithmeticService.add(
int
,
int
) || execution(
int
com
..ArithmeticService.div(
int
,
int
))g")
@Around
(value = "execution(*
com
..*Service.*(..))")
public Object log(ProceedingJoinPoint joinPoint){
Object result = null;
System.out.println("前置通知:任何时候都执行");
try {
result = joinPoint.proceed();
System.out.println("返回通知");
} catch (Throwable e) {
//
TODO
Auto
-
generated catch block
e.printStackTrace();
System.out.println("异常通知");
}
System.out.println("后置通知:任何时候都执行");
return result;
}
*/
}
测试:
ApplicationContext
ac
=
null
;
ArithmeticService
arts
=
null
;
@Before
public
void
init(){
ac
=
new
ClassPathXmlApplicationContext(
"beans.xml"
);
arts
=
ac
.getBean(
"arithmeticServiceImpl"
, ArithmeticService.
class
);
}
@Test
public
void
demo
(){
int
result
=
arts
.add(1, 1);
System.
out
.println(
result
);
}
}