代码改变世界

Java面试题总结论(二)-IOC、AOP、Spring、注解

2021-04-21 14:10  查士丁尼  阅读(683)  评论(0编辑  收藏  举报

什么是Java的反射

反射就是在运行时才知道要操作的类是什么,并且可以在运行时获取类的完整构造,并调用对应的方法。

Java获取Class类对象的三个方法

第一种,使用 Class.forName 静态方法。当你知道该类的全路径名时,你可以使用该方法获取 Class 类对象。

Class clz = Class.forName("java.lang.String");

第二种,使用 .class 方法。

这种方法只适合在编译前就知道操作的 Class。

Class clz = String.class;

第三种,使用类对象的 getClass() 方法。

String str = new String("Hello");
Class clz = str.getClass();

什么是Java的范型?

泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。

“泛型” 意味着编写的代码可以被不同类型的对象所重用。

什么是类型擦除?

指通过类型参数合并,将泛型类型实例关联到同一份字节码上。编译器只为泛型类型生成一份字节码,并将其实例关联到这份字节码上。类型擦除的关键在于从泛型类型中清除类型参数的相关信息,并且再必要的时候添加类型检查和类型转换的方法。

Array支持范型吗?

不支持,建议用List替代。

什么是 IoC

IoC (Inversion of control )控制反转/反转控制。它是一种思想不是一个技术实现。描述的是:Java 开发领域对象的创建以及管理的问题。

IoC 好处

对象之间的耦合度或者说依赖程度降低;

资源变的容易管理;比如你用 Spring 容器提供的话很容易就可以实现一个单例。

什么是依赖注入

把有依赖关系的类放到容器中,解析出这些类的实例,就是依赖注入。目的是实现类的解耦。

IoC 最常见以及最合理的实现方式叫做依赖注入(Dependency Injection,简称 DI)。

什么是 AOP

一是采用动态代理技术,利用截取消息的方式,对该消息进行装饰,以取代原有对象行为的执行;二是采用静态织入的方式,引入特定的语法创建“方面”,从而使得编译器可以在编译期间织入有关“方面”的代码。

AOP 解决了什么问题

在不改变原有业务逻辑的情况下,增强横切逻辑代码,根本上解耦合,避免横切逻辑代码重复。

AOP实现机制

AOP代理主要分为静态代理和动态代理,静态代理的代表为AspectJ;而动态代理则以Spring AOP为代表。静态代理是编译期实现,动态代理是运行期实现,可想而知前者拥有更好的性能。

AOP实际应用

事务管理、权限、日志、缓存

Autowired 作用

@Autowired 是一个注释,它可以对类成员变量、方法及构造函数进行标注,让 spring 完成 bean 自动装配的工作。

注解Autowired、Value和Resource区别

Value注入配置项

Autowired注入对象

Autowired,Spring注解,默认按照类型装配,默认依赖对象必须存在,按照名称装配需要配合Qualifier注解使用

Resource,JDK注解(推荐,减少与Spring耦合),默认按照名称装配,匹配不到按照类型装配。

Spring常用注解

Configuration声明配置类

Bean申明方法返回值为bean

Configuration申明类为配置类

ComponentScan对Component进行扫描

WishlyConfiguration=Configuration+ComponentScan

Component组件

Service业务逻辑层

Repository数据访问层

Controller控制器

Autowired、Inject、Resource注入bean

Profile设定当前配置环境

Conditional决定bean是否被实例化

Aspect申明切面

After执行之后执行

Before执行之前执行

Around方法执行之前与之后执行

PointCut声明切点

EnableAsync开启对异步任务支持

Asyc申明异步任务

EnableScheduling开启计划任务的支持

Scheduled申明一个任务

拦截器和过滤器

过滤器是一个程序,它先于与之相关的servlet或JSP页面运行在服务器上。它是随你的web应用启动而启动的,只初始化一次,以后就可以拦截相关请求,只有当你的web应用停止或重新部署的时候才销毁。

请求和回应的过滤,传入的request,response提前过滤掉一些信息,或者提前设置一些参数,然后再传入servlet或者struts的action进行业务逻辑,比如过滤掉非法url

拦截器,在AOP(Aspect-Oriented Programming)中用于在某个方法或字段被访问之前,进行拦截然后在之前或之后加入某些操作。比如日志,安全等。

区别

①拦截器是基于java的反射机制的,而过滤器是基于函数回调。

②拦截器不依赖与servlet容器,过滤器依赖与servlet容器。

③拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用。

④拦截器可以访问action上下文、值栈里的对象,而过滤器不能访问。

⑤在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次。

⑥拦截器可以获取IOC容器中的各个bean,而过滤器就不行,这点很重要,在拦截器里注入一个service,可以调用业务逻辑。

拦截器是被包裹在过滤器之中的。

 Spring注解@Component、@Repository、@Service、@Controller区别

Spring2.5等效,方便识别和后期扩展

Java的代理有几种

静态代理在编译时就已经实现,编译完成后代理类是⼀个实际的class⽂件 动态代理是在运⾏时动态⽣成的,即编译完成后没有实际的class⽂件,⽽是在运⾏时动态⽣成 类字节码,并加载到JVM中。

动态代理分为JDK方式和cglib方式

JDK 动态代理通过反射来接受被代理的类,并且要求被代理的类必须实现一个接口。JDK 动态代理的核心是 InvocationHandler 接口和 Proxy 类。

如果目标没有实现接口,那么Spring AOP 会选择使用 CGLIB 来动态代理目标类。CGLIB(Code Generration Library)是一个代码生成的类库,可以在运行时动态的生成某个类的子类,注意,CGLIB 是通过继承的方式做的动态代理,因此如果某个类被标记为 finnal,那么它是无法使用 CGLIB 做动态代理的,诸如 private 方法也是不可以作为切面的。

1.JDK动态代理是实现了被代理对象的接口,Cglib是继承了被代理对象。

2.JDK和Cglib都是在运行期生成字节码,JDK是直接写Class字节码,Cglib使用ASM框架写Class字节码,Cglib代理实现更复杂,生成代理类比JDK效率低。

3.JDK调用代理方法,是通过反射机制调用,Cglib是通过FastClass机制直接调用方法,Cglib执行效率更高。

如何自定义注解

关键词@interface

元注解:

@Target表明注解可以应用的java元素类型

@Retention注解生命周期

@Document表明注解元素可以被Javadoc等工具文档化

@Interited表明使用了@Inherited注解的注解,所标记的类的子类也会拥有这个注解

写过自定义注解吗?

拦截器