Springaop与动态代理

Spring AOP(面向切面编程)是 Spring 框架的重要模块之一,它通过 AOP 减少代码重复和降低模块之间的耦合,使代码更加模块化和可复用。下面举一个 Spring AOP 的例子:

假设我们有一个接口IService:

```java

public interface IService {

    void doSomething();

}

```

现在我们想在 `doSomething()` 方法执行前后打印一些日志,这时候我们可以使用 Spring AOP 来实现这一功能。

首先,我们定义一个切面(Aspect)类,用于实现日志处理的功能:

```java

@Component

@Aspect

public class LogAspect {

    private static final Logger logger = LoggerFactory.getLogger(LogAspect.class);

    @Before("execution(* your.package.IService.doSomething(..))")

    public void beforeDoSomething() {

        logger.info("before doSomething()");

    }

    @("execution(* your.package.IService.doSomething(..))")

    public void afterDoSomething() {

        logger.info("after doSomething()");

    }

}

```

在上述代码中,我们使用了 Spring AOP 的注解 @Aspect 来表明此类是一个切面类。然后,我们定义了两个方法,分别用于在 `doSomething()` 方法执行前后打印日志。

在这两个方法中,我们使用了 @Before 和 @After 注解,它们分别表示在被注解的方法执行前和执行后执行通知(Advice)。通知是切面的核心功能之一,用于在程序执行的特定时间点,执行特定的操作。

在`@Before`和`@After`注解中,我们使用了切点(Pointcut)表达式来表示要拦截的方法,这里表示拦截 `IService` 接口的 `doSomething()` 方法执行时打印日志。

接着,在 IOC(控制反转)容器中注入 IService 类:

```java

@Service

public class ServiceImpl implements IService {

    @Override

    public void doSomething() {

        // do something

    }

}

```

最后,我们可以在应用程序中通过下面的方式调用 IService 的 `doSomething()` 方法,从而触发 Spring AOP 的切面逻辑并打印日志:

```java

@Autowired

private IService service;

service.doSomething();

```

通过以上步骤,我们就实现了在 `doSomething()` 方法执行前后打印日志的功能,这就是 Spring AOP 的一个简单应用。

下面是几道面试题:

dd6f9276dbef486daf1e87543de85937.jpg

ffbd168f93214731965cf45956b779b1.jpg

什么是动态代理?为什么引入动态代理?好处?与aop什么关系

java在运行时动态创建代理对象,对方法进行代理增强

如果业务代码中很多相同的,与业务无关的代码,也就是觉得自己干的事太多,可以通过代理转移这部分的职责。

我们需要一个接口告诉中介公司找什么样的代理,也就是我们需要代理增强的方法定义到一个接口中。

一般在java中我们规定需要进行代理的类   ->实现这个告知中介公司要增强哪些方法的接口

1.需要代理的类 其中sing方法和dance方法需要代理

public class Bigstar implements star {
private String name;

public Bigstar(String name) {
this.name = name;
}


@Override
public String sing(String name) {
System.out.println(this.name+"正在唱着动人的歌曲");
return this.name+"谢谢大家";
}

@Override
public void dance() {
System.out.println(this.name+"正在跳舞");

}
public void say(){
System.out.println("你们好!");
}}

2.需要代理的方法抽象出来成一个接口,如下:

 

public interface star {


public String sing(String name);


public void dance();

}

3.工具类来创建代理对象

public class ProxyUtils {
//传入Bigstar代表要创建它的代理对象,返回值是star接口类型变量 就是代理对象
//newProxyInstance 第一个参数 一般是当前类的class获得类加载器
//第二个参数 class[]interface 要代理的方法的接口
//第三个参数 代理对象要执行的代码逻辑
public static star createBigstarproxy(Bigstar bigstar){
dy_proxy.star starproxy = (star) Proxy.newProxyInstance(ProxyUtils.class.getClassLoader(), new Class[]{star.class}, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (method.getName().equals("sing")) {
System.out.println("准备话筒,准备场地,收钱");//增强

} else if (method.getName().equals("dance")) {
System.out.println("准备舞台,准备场地,收钱");//增强
}
//最后调用杨超越自己的方法。

return method.invoke(bigstar, args);
}
});
return starproxy;
}
}

4.测试类进行测试

public static void main(String[] args) {
star starproxy = ProxyUtils.createBigstarproxy(new Bigstar("杨超越"));
String sing = starproxy.sing("好日子");
System.out.println(sing);
starproxy.dance();
}

注意:当我们调用starproxy.sing()方法,走的是其中invoke方法的逻辑,走的是匿名内部类实现接口的逻辑

new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (method.getName().equals("sing")) {
System.out.println("准备话筒,准备场地,收钱");//增强

} else if (method.getName().equals("dance")) {
System.out.println("准备舞台,准备场地,收钱");//增强
}
//最后调用杨超越自己的方法。

return method.invoke(bigstar, args);
}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值