Spring面试

1.说说你对Spring的IOC机制的理解可以吗?

Spring IOC框架,控制反转,依赖注入

以前是xml文件来进行一个配置,后面进化到了基于注解来进行自动依赖注入

Spring ioc,spring 容器,根据xml配置,或者是你的注解,去实例化你的一些bean对象,然后根据xml配置或者注解,去对bean对象之间的应用关系,去进行依赖注入,某个bean依赖了另外一个bean

底层的核心技术,反射,它会通过反射的技术,直接根据你的类去自己构建对应的对象出来,用的就是反射的技术

ps:自由发挥

2.说说你对Spring的AOP机制的理解可以吗?

比如说我们平时有两个类,MyserviceA和MyserviceB,在类里面有他自己的方法,doServiceA和doServiceB,在方法里面我们会进行增删改查的操作,一般进行这种操作我们都会考虑到事务,所以我们会加入开启事务,回滚事务,提交事务,关闭事务的代码。通过AOP,我们做一个切面,比如MyserviceXXXX的这种类,在这些类的所有方法中,都去织入一些代码,在所有这些方法刚开始运行的时候,都会先去开启一个事务,在所有这些方法运行完毕后,去根据是否抛出异常来判断事务的具体操作

AOP的核心技术就是动态代理

ps:看下手写代理模式的代码。

3.了解过cglib动态代理吗?他跟jdk动态代理的区别是什么?

优先jdk动态代理,其次是cglib动态代理

动态代理其实就是动态的创建一个代理类出来,创建这个代理类的实例对象,在这个里面引用你真正自己写的类,所有的方法的调用,都是先走代理类的对象,它负责做一些代码上的增强,再去调用你自己写的那个类

如果你的类是实现了某个接口的,spring aop 会使用jdk动态代理,生成一个跟你实现同样接口的一个代理类,构造一个实例对象出来,jdk动态代理,它其实是在你的类有接口的时候,就会来使用

很多时候我们可能某个类是没有实现接口的,spring aop会改用cglib来生成动态代理,他是生成你的类的一个子类,它可以动态生成字节码,覆盖你的一些方法,在方法里加入增强的代码

public class CglibMeipo implements MethodInterceptor {


    public Object getInstance(Class<?> clazz) throws Exception {
            Enhancer enhancer = new Enhancer();
            //要把clazz设置为即将生成的新类父类
            enhancer.setSuperclass(clazz);
            enhancer.setCallback(this);

            return enhancer.create();

    }

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("我是媒婆:我要给你找对象,已经拿到你的需求");
        System.out.println("开始物色");
        methodProxy.invokeSuper(o,objects);
        System.out.println("如果合适的话,准备办事");
        return null;
    }
}
public class JdkMeipo implements InvocationHandler {
    //把被代理的对象保存下来
    private Person target;

    public Object getInstance(Person target) throws Exception{
        this.target = target;
//        Class clazz = Class.forName(this.target.getClass().getName());
        Class clazz = target.getClass();
        return Proxy.newProxyInstance(clazz.getClassLoader(),clazz.getInterfaces(),this);
        //loader:Proxy.newProxyInstance的三个参数分别代表什么
        //interfaces:用哪个类加载器去加载类对象
        //h:动态代理方法执行时,会调用h里面的invoke方法去执行
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("我是媒婆:我要给你找对象,现在已经拿到你的需求");
        System.out.println("开始物色");

        method.invoke(this.target,args);

        System.out.println("如果合适的话,就准备办事");
        return null;
    }
}

4.能说说Spring中的Bean是线程安全的吗?

spring容器中的bean可以分为5个范围:

(1)singleton:默认,每个容器中只有一个bean的实例

(2)prototype:为每一个bean请求提供一个实例

一般来说下面三种作用域一般不会用

(3)request:为每一个网络请求创建一个实例,在请求完成以后,bean会失效并被垃圾回收器回收

(4)session:与request范围类似,确保每个session中有一个bean的实例,在session过期后,bean会随之失效

(5)global-session

那么是不是线程安全的了?答案是否定的,比如说在某个类有个int data = 0变量,类里面有个方法进行data++操作,当多个线程去请求bean就会发生线程不安全,怎么解决,就是不要去访问内存中的共享数据,而是去访问数据库。

5.Spring的事务实现原理是什么?能聊一聊你对事务传播机制的理解吗?

 

posted @ 2020-05-31 21:01  MonsterZL  阅读(189)  评论(0编辑  收藏  举报