IOC 原理 和DI 原理
1、IOC 控制反转,是一种思想,DI依赖注入就是IOC思想的一种很好的应用。
2、依赖注入有三种方式:通过set注入,通过属性注入,通过构造函数注入
3、通过spring 容器获取依赖,不用管依赖是怎么生成的,直接交给spring容器处理,这里便是依赖实例化的控制权交给了spring,我们只需引用即可。
spring启动
1、spring程序的启动,会去扫描获取bean信息,例如xml 定义的bean,@bean注解,@configuration、@component等注解修饰的类或是bean
2、将获取到的bean信息装载到beanDefinitionMap里面,即bean定义注册表;
3、spring 根据bean定义注册表实例化bean,将bean实例放到spring容器中。即bean缓存池中(singletonObjects)
AOP原理
1、AOP的实现:aop主要是通过jdkProxy 和Cglib来实现的,默认策略是若是目标类是接口,则用JDKProxy来实现,否则用cglib来实现
2、JDKProxy的核心:实现InvocationHandler接口,重写invoke方法,是通过反射来实现的。
原理:
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("代理执行" +method.getName() + "方法");
*/
//代理过程中插入监测方法,计算该方法耗时
MonitorUtil.start();
Object result = method.invoke(target, args);
MonitorUtil.finish(method.getName());
return result;
}
使用:
//创建一个与代理对象相关联的InvocationHandler
InvocationHandler stuHandler = new StuInvocationHandler<Person>(zhangsan);
//创建一个代理对象stuProxy来代理zhangsan,代理对象的每个执行方法都会替换执行Invocation中的invoke方法
Person stuProxy = (Person) Proxy.newProxyInstance(Person.class.getClassLoader(), new Class<?>[]{Person.class}, stuHandler);
3、cglib:以继承的方式动态生成目标类的代理类,借助ASM实现的,代理类不能用final修饰
ProxyFactory proxyFactory = new ProxyFactory(new UserDaoImpl());
UserDaoImpl proxy = (UserDaoImpl) proxyFactory.getProxyInstance();
proxy.save();
spring Bean的作用域
1、 singleton:spring的默认作用域
2、prototype:针对每个getBean的请求,容器都会创建一个bean实例
3、request:每个http请求都会创建一个bean
4、session: 每个session 都会创建一个bean
5、globalSession: 全局session作用域
getBean方法的代码逻辑
1、转换beanName–从缓存种加载实例–实例化bean–检测parentBeanFactory–初始化依赖的Bean–创建bean
2、 getBean 获取到的实例是代理类
3、getBean()-- doGetBean()–createBean()–doCreateBean()–返回bean
spring的三级缓存
1、singletonObjects:用于存放完全初始化好的 bean,从该缓存中取出的 bean 可以直接使用
2、earlySingletonObjects: 提前曝光的单例对象的cache,存放原始的 bean 对象(尚未填充属性),用于解决循环依赖
3、singletonFactories:单例对象工厂的cache,存放 bean 工厂对象,用于解决循环依赖
循环依赖的解决方法
利用spring的三级缓存解决,其中earlySingletonObjects是将单例提前暴露出去,对象只是实例化并没有初始化。
不能解决的情况:
- 构造器注入循环依赖
- prototype field属性注入循环依赖
能解决的情况: - field属性注入(setter方法注入)循环依赖