笔者福利
以下是小编自己针对马上即将到来的金九银十准备的一套“面试宝典”,不管是技术还是HR的问题都有针对性的回答。
有了这个,面试踩雷?不存在的!
回馈粉丝,诚意满满!!!
对切面的理解
程序中的每一个模块或者说功能,任何一个模块中都要记录它的日志、事务、安全验证等等,给我们带来的工作量非常大。
当程序到达某种规模时,尤其是格式调整之类的,这种改动量是非常大的。如果通过切面方式,对开发人员是不可见的,默认地会对每一个子模块记录日志等这些工作。通过预编译或者动态代理的方式来执行这个功能,
对开发人员是透明,他不需要知道。
切面是和功能垂直的,也就是切面是横切与各个功能之上的
AOP几个相关概念
①切面—一个关注点的模块化,这个关注点可能会横切多个对象
②连接点–程序执行过程中的某个特定的点
③通知----在切面的某个特定的连接点上执行的动作
④切入点–匹配连接点的断言,在AOP中通知和一个切入点表达式关联
⑤引入----在不修改类代码的前提下,为类添加新的方法和属性
⑥目标对象-被一个或者多个切面所通知的对象
⑦AOP代理–AOP框架创建的对象,用来实现切面契约(包括通知方法执行等功能)
⑧织入—把切面连接到其他的应用程序类型或者对象上,并且创建一个被通知的对象,分为:编译时织入,执行时织入
Spring的AOP实现
·纯java实现,无需特殊的编译过程·,不需要控制类加载器层次
·目前只支持方法执行连接点(通知Spring Bean的方法执行)
·不是为了提供最完整的AOP实现(尽管它非常强大);而是侧重于提供一种AOP实现和Spring IOC容器之间的整合,用于帮助解决企业应用中的常见问题
·Spring AOP不会与AspectJ竞争,从而提供综合全面的AOP解决方案。
把对象类 切面类(与通过配置aop:config来指定普通类成为切面类不同,使用ProxyFactoryBean的切面类都需要继承AOP API并重写方法来实现传递通知)都作为
成员属性放在一个ProxyFactoryBear类中 通过在ProxyFactoryBear类中的方法,指定对象类的切入点并配置切面(不再是通过配置文件进行切面配置,而是在IOC容器中配置)。并且最后返回一个Object类(可以理解为对象类对象通过一系列切面类方法加工、植入通知后的结果对象)
1 核心:代理工厂(ProxyFactoryBean)
*必备属性:代理目标类(target,可以使用引用bean或匿名bean,推荐后者)、通知(advisor或advice)
*可选属性:代理接口(proxyInterfaces,使用JDK动态代理)、代理类属性(proxyTargetClass的值为true时,则使用cglib代理)
2 切入点常用bean:NameMatchMethodPointcut
*根据名称自动匹配方法,可以使用通配符的形式进行匹配,匹配结果放在数组mappedNames中
*mappedNames节点可以使用list子节点进行设置匹配项(可以使用通配符)
3 通知常用bean:DefaultPointcutAdvisor
*必备属性:advice和pointcut
*可以使用构造注入或设置注入的形式注入两个属性
使用ProxyFactoryBean,通知和切入点可以由IOC容器管理
-
被代理类没有实现任何接口,用的是CGLIB动态代理,否则使用的是JDK代理
-
ProxyFactoryBean为true,无论是否实现了接口,都强制使用CGLIB
-
如果proxyInterfaces属性设置为一个或者多个全限定接口名,使用的是JDK代理
Spring AOP API小结
一、Pointcut
1.实现之一:NameMatchMethodPointcut,根据方法名进行匹配
2.成员变量:mappedNames,匹配方法名集合
二、Advice
1.Before Advic – 继承MethodBeforeAdvice接口
2.Throws Advice – 继承ThrowsAdvice接口
3.After Returning Advice – 继承AfterReturningAdvice接口
4.Interception Around Advice – 继承MethodInterceptor接口
5.Introduction Advice
三、ProxyFactoryBean
1.不指定接口
2.指定接口
3.简化proxy使用
注解方式实现Aspectj
@configuration
@EnableAspectjAutoProxy
public class Appcinfig{
}aop:sapectj-autoproxy/
AspectJ是编译期的AOP
检查代码并匹配连接点与切入点的代价是昂贵的
一个好的切入点应该包括以下几点
-
选择特定类型的连接点,如:execution,get,set,call,handler
-
确定连接点范围,如:within,withincode
-
匹配上下文信息,如:this,target,@annotation
@AspectJ切面使用@Aspect注解配置,拥有@Aspect的任何bean将被Spring自动识别并应用
用@Aspect注解的类可以有方法和字段,他们也可能包括切入点(pointcut),通知(Advice)和引入(introduction)声明
@Aspect注解是不能够通过类路径自动检测发现的,所以需要配合使用@Component注释或者在xml配置bean
@Aspect注解是不能够通过类路径自动检测发现的,所以需要配合使用@Component注释或者在xml配置bean
一个类中的@Aspect注解标识它为一个切面,并且将自己从自动代理中排除
package org.xyz;
import org.aspectj.lang.annotation.Aspect;
@Aspect
public class NotVeryUsefulAspect{
}
使用@Pointcut注解,方法的返回值类型必须是void
@component (把普通pojo实例化到spring容器中,相当于配置文件中的)
利用注解的方式实现切面(之前是使用xml配置的方式)
在xml文件中配置
aop:aspectj-autoproxy/
在切面类的文件中,Component表示可以被识别为一个bean,Aspect表示是一个切面的类,pointcut的方法在注解上表明了切入点的类,before,afterReturning,afterThrowing,after与之前相似,其中的参数表示切入的方法返回值或者抛出的错误信息
@Component
@org.aspectj.lang.annotation.Aspect
public class Aspect {
@Pointcut(“execution(* com.aspectj.Biz.*(…))”)
public void pointcut() {
}
// @Pointcut(“within(* com.aspect.*)”)
// public void bizPointcut() {
// }
@Before(“pointcut()”)
public void before() {
System.out.println(“Before…”);
}
@AfterReturning(pointcut = “pointcut()”, returning = “returnValue”)
public void afterReturning(Object returnValue) {
System.out.println(“AfterReturning…” + returnValue);
}
@AfterThrowing(pointcut = “pointcut()”, throwing = “e”)
public void afterThrow(RuntimeException e) {
System.out.println(“AfterThrowing…” + e.getMessage());
}
@After(“pointcut()”)
public void after() {
System.out.println(“After…”);
}
}
写在最后
很多人感叹“学习无用”,实际上之所以产生无用论,是因为自己想要的与自己所学的匹配不上,这也就意味着自己学得远远不够。无论是学习还是工作,都应该有主动性,所以如果拥有大厂梦,那么就要自己努力去实现它。
最后祝愿各位身体健康,顺利拿到心仪的offer!
由于文章的篇幅有限,所以这次的蚂蚁金服和京东面试题答案整理在了PDF文档里
…(img-Vitrj6YU-1715091493679)]
[外链图片转存中…(img-gUQoizNd-1715091493679)]
[外链图片转存中…(img-RunL0d0f-1715091493680)]