【跟着狂神学spring】spring系列二aop
作者:互联网
AOP: Aspect oriented Programming,面向切面变成,通过预编译和运行期间动态代理实现程序功能。在不修改代码情况下,给程序加功能,当然也可以直接用静态代理或者动态代理去做。不过按照spring说法
aop允许分离应用的业务逻辑和系统级服务
主要功能
百度说是:把日志记录、性能统计、安全控制、事务处理、异常处理从业务逻辑代码剥离出来
静态代理方式
代理接口: Rent
真实角色:Host
代理:Proxy
public interface Rent {
void rent();
}
public class Host implements Rent {
@Override
public void rent() {
System.out.println("真实对象出租房屋");
}
}
public class Proxy implements Rent{
private Host host; //代理角色依赖与真实角色
public Proxy() {
}
public Proxy(Host host) {
this.host = host;
}
public void see(){
System.out.println("带客户看房源");
}
@Override
public void rent() {
see();
host.rent();
contact();
}
public void contact() {
System.out.println("签合同");
}
}
测试端
public class Client {
public static void main(String[] args) {
Host host = new Host();
Proxy proxy = new Proxy(host);
proxy.rent();
}
}
动态代理
不显式生成那个Proxy代理类
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* Proxy和InvocationHandler两个类
*/
public class ProxyInvocationHandler implements InvocationHandler{
//被代理的接口
private Object target;
//注入代理的接口
public void setTarget(Object target){
this.target = target;
}
//生成得到代理类
public Object getProxy(){
return Proxy.newProxyInstance(this.getClass().getClassLoader(),
target.getClass().getInterfaces(), this);
}
//处理代理实例,并返回结果
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
log(method.getName());
Object result = method.invoke(target, args);
return result;
}
public void log(String msg ){
System.out.println("执行 " + msg + "方法");
}
}
测试端:
public class Client {
public static void main(String[] args) {
/**
* 主要设计InvocationHandler 、 Proxy
*/
Host host = new Host();//真实代理的角色
//代理角色 运行时创建
ProxyInvocationHandler hander = new ProxyInvocationHandler();
// //设置代理的对象
hander.setTarget(host);
//生成动态代理类
Rent1 proxy = (Rent1) hander.getProxy();
proxy.rent();
}
}
【bug】Rent1与ProxyInvocationHandler在同一个包下,然后尽然说找不到这个Rent1,尚未解决这个问题
AOP
案例
UserSerivice
UserServiceImpl
public interface UserService {
void add();
void delete();
void search();
void update();
}
public class UserServiceImpl implements UserService{
public UserServiceImpl() {
}
@Override
public void add() {
System.out.println("添加一个用户");
}
@Override
public void delete() {
System.out.println("delete一个用户");
}
@Override
public void search() {
System.out.println("search一个用户");
}
@Override
public void update() {
System.out.println("update一个用户");
}
}
实现AOP三种方式
<?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
https://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 注册bean-->
<bean id="userService" class="com.example.demo03.UserServiceImpl" />
<bean id="log" class="com.example.demo03.Log"/>
<bean id="afterlog" class="com.example.demo03.AfterLog"/>
<!-- 方式一 使用原声的spring api接口-->
<!-- 配置aop-->
<!-- <aop:config>-->
<!--<!– 切入点:expression表达式,execution(要执行的位置!* 报名)–>-->
<!-- <aop:pointcut id="pointcut" expression="execution(* com.example.demo03.UserServiceImpl.*(..))"/>-->
<!--<!– 执行环绕增加–>-->
<!-- <aop:advisor advice-ref="log" pointcut-ref="pointcut"/>-->
<!-- <aop:advisor advice-ref="afterlog" pointcut-ref="pointcut"/>-->
<!-- </aop:config>-->
<!-- 方式二 使用-->
<!-- <bean id="diy" class="com.example.demo03.DIY"/>-->
<!-- <aop:config>-->
<!--<!– 自定义切面,ref是要引用的类–>-->
<!-- <aop:aspect ref="diy">-->
<!--<!– 切入点–>-->
<!-- <aop:pointcut id="point" expression="execution(* com.example.demo03.UserServiceImpl.*(..))"/>-->
<!--<!– 通知–>-->
<!-- <aop:before method="before" pointcut-ref="point"/>-->
<!-- <aop:after method="after" pointcut-ref="point"/>-->
<!-- </aop:aspect>-->
<!-- </aop:config>-->
<!-- 方式三 使用注解方式-->
<bean id="annotationpointcut" class="com.example.demo03.AnnotationPointCut"/>
<!-- aop:aspectj-autoproxy标签中 有个默认代理类 -->
<!-- 开启注解支持 jdk(默认) cglib-->
<aop:aspectj-autoproxy proxy-target-class="false"/>
</beans>
方式一中用到的Log和AfterLog类
import org.springframework.aop.MethodBeforeAdvice;
import java.lang.reflect.Method;
public class Log implements MethodBeforeAdvice {
/**
*
* @param method:要执行的目标对象的方法
* @param objects: 参数
* @param o: 目标对象
* @throws Throwable
*/
@Override
public void before(Method method, Object[] objects, Object o) throws Throwable {
System.out.println(o.getClass().getName() + "的"+method.getName() + "被执行了");
}
}
import org.springframework.aop.AfterReturningAdvice;
import java.lang.reflect.Method;
public class AfterLog implements AfterReturningAdvice {
/**
*
* @param o: 返回的结果
* @param method
* @param objects
* @param o1
* @throws Throwable
*/
@Override
public void afterReturning(Object o, Method method, Object[] objects, Object o1) throws Throwable {
System.out.println("调用了"+method.getName() + "返回值:" + o);
}
}
方式二中使用的DIY类
public class DIY{
public void before(){
System.out.println("调用了before" );
}
public void after(){
System.out.println("调用了after" );
}
}
方式三使用到的直接类
package com.example.demo03;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
@Aspect //表明这个类是一个切面
public class AnnotationPointCut {
@Before("execution(* com.example.demo03.UserServiceImpl.*(..))")
public void befor(){
System.out.println("before");
}
@After("execution(* com.example.demo03.UserServiceImpl.*(..))")
public void after(){
System.out.println("after");
}
@Around("execution(* com.example.demo03.UserServiceImpl.*(..))")
public void aroud(ProceedingJoinPoint jp) throws Throwable {
System.out.println("环绕前");
Signature signature = jp.getSignature();
System.out.println("signature" + signature);
Object proceed = jp.proceed(); //执行方法
System.out.println("环绕后");
}
}
标签:spring,void,Object,System,aop,println,public,神学,out 来源: https://blog.csdn.net/Alearn_/article/details/120461237