*/
@Aspect
public class MyAspect {
@Around("execution(* login(..))")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("---- aspect log ----");
Object ret = joinPoint.proceed();
return ret;
}
}
<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 id="userService" class="com.yusael.aspect.UserServiceImpl"/>
<!--
切面:
1. 额外功能
2. 切入点啊
3. 组装切面
-->
<bean id="around" class="com.yusael.aspect.MyAspect"/>
<!--告知 Spring 基于注解进行 AOP 编程-->
<aop:aspectj-autoproxy/>
</beans>
```
[](https://gitee.com/vip204888/java-p7)切入点复用
------------------------------------------------------------------------
切入点复用:在切面类中定义⼀个函数,上面用 `@Pointcut` 注解。
通过这种方式定义切入点表达式,后续更加有利于切入点复用。
```
@Aspect
public class MyAspect {
@Pointcut("execution(* login(..))")
public void myPoincut() {}
@Around(value = "myPoincut()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("---- aspect log ----");
Object ret = joinPoint.proceed();
return ret;
}
@Around(value = "myPoincut()")
public Object around1(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("---- aspect transaction ----");
Object ret = joinPoint.proceed();
return ret;
}
}
```
[](https://gitee.com/vip204888/java-p7)切换动态代理的创建方式(JDK、Cglib)
-----------------------------------------------------------------------------------------
AOP 底层实现 2 种代理创建方式:
1. JDK:通过 **实现接口,做新的实现类** 创建代理对象
2. Cglib:通过 **继承父类,做新的子类** 创建代理对象
**默认情况 AOP 编程 底层应用 JDK动态代理创建方式**。
基于注解的 AOP 开发 中切换为 Cglib:
```
<aop:aspectj-autoproxy proxy-target-class="true"/>
```
传统的 AOP 开发 中切换为 Cglib:
```
<aop:config proxy-target-class="true">
...
</aop:config>
```
[](https://gitee.com/vip204888/java-p7)AOP 开发中的一个坑(业务方法互相调用)
----------------------------------------------------------------------------------------
**坑!**:在同⼀个业务类中,进⾏业务方法间的相互调用,只有最外层的方法,才是加入了额外功能(内部的方法,通过普通的方式调用,都调用的是原始方法)。如果想让内层的方法也调用代理对象的方法,就要实现 `AppicationContextAware` 获得⼯厂,进而获得代理对象。
```
public class UserServiceImpl implements UserService, ApplicationContextAware {
private ApplicationContext ctx;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
ctx = applicationContext;
}
@Override
public void register(User user) {
System.out.println("UserServiceImpl.register 业务运算 + DAO");
// this.login("zhenyu", "123456"); // 这么写调用的是本类的 login 方法, 即原始对象的 login 方法
// 为什么不在这里创建一个工厂获取代理对象呢?
// Spring的工厂是重量级资源, 一个应用中应该只创建一个工厂.
// 因此我们必须通过 ApplicationContextAware 拿到已经创建好的工厂
UserService userService = (UserService) ctx.getBean("userService");
userService.login("yusael", "123456");
}
@Override
public boolean login(String name, String password) {
System.out.println("UserServiceImpl.login 业务运算 + DAO");
# **结尾**
![查漏补缺:Java岗 千+道面试题Java基础+全家桶+容器+反射+异常等](https://img-blog.csdnimg.cn/img_convert/80b15114d22cbd03a1942f2533df85f7.png)
这不止是一份面试清单,更是一种”被期望的责任“,因为有无数个待面试者,希望从这篇文章中,找出通往期望公司的”钥匙“,所以上面每道选题都是结合我自身的经验于千万个面试题中经过艰辛的两周,一个题一个题筛选出来再次对好答案和格式做出来的,面试的答案也是再三斟酌,深怕误人子弟是小,影响他人仕途才是大过,也希望您能把这篇文章分享给更多的朋友,让他帮助更多的人,帮助他人,快乐自己,最后,感谢您的阅读。
**[资料领取方式:戳这里免费获取](https://gitee.com/vip204888/java-p7)**
个待面试者,希望从这篇文章中,找出通往期望公司的”钥匙“,所以上面每道选题都是结合我自身的经验于千万个面试题中经过艰辛的两周,一个题一个题筛选出来再次对好答案和格式做出来的,面试的答案也是再三斟酌,深怕误人子弟是小,影响他人仕途才是大过,也希望您能把这篇文章分享给更多的朋友,让他帮助更多的人,帮助他人,快乐自己,最后,感谢您的阅读。
**[资料领取方式:戳这里免费获取](https://gitee.com/vip204888/java-p7)**
**由于细节内容实在太多啦,在这里我花了两周的时间把这些答案整理成一份文档了,在这里只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容!**