Spring的AOP
代理模式
- jdk动态代理
利用拦截器+反射生成接口的匿名类,在调用具体方法前调用invokeHandle来处理。
所以jdk动态代理只能为实现了接口的类服务。 - cglib动态代理
利用ASM框架,对代理对象类生成的class文件加载进来,通过修改其字节码生成子类来处理。
Cglib是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法,并覆盖其中方法的增强,但是因为采用的是继承,所以该类或方法最好不要生成final,对于final类或方法,是无法继承的。
Spring的Bean的作用域
bean的作用域规定了哪种类型的对象返回给调用者。
- singleton 单例bean
- prototype 多例bean
- request 每次http请求都会创建一个新的bean
- session 同一个session共享一个bean
- application 限定一个Bean的作用域为ServletContext的生命周期。该作用域仅适用于web的Spring WebApplicationContext环境。
事务的传播行为
当一个事务方法A调用另一个事务方法B时,B是否开启一个新事物,或者在A的事务中运行,这由spring的事务传播行为决定。
spring的单例模式
spring使用注册表的方式创建单例对象,将对象放到currenthashmap中来实现单例。
1.需要单例的类
public class Student {
//假装有很多属性和方法
}
2.创建注册表
/**
* Created by liuruijie on 2017/2/13.
* 单例注册表
*/
public class BeanFactory {
/**
* 这些是维护此注册表的,
* 因为不是重点
* 所以采用了最简单的方式
* 可以用其他方式
*/
private static BeanFactory beanFactory = new BeanFactory();
private BeanFactory(){
}
// 获取bean工厂对象
public static BeanFactory getInstance() {
return beanFactory;
}
//缓存单例对象的hash表
private final HashMap<String, Object> cacheMap = new HashMap<>();
//通过类名获取其单例对象,如果注册表中没有该对象,则创建,否则返回该对象。
public Object getBean(String className) {
Object bean = cacheMap.get(className);
//使用双重检测锁来实现单例
if (bean == null) {
synchronized (this.cacheMap) {
//第二次检测
bean = cacheMap.get(className);
if (bean == null) {
try {
bean = Class.forName(className).newInstance();
} catch (InstantiationException e) {
System.err.println("could not instance an object of type:" + className);
e.printStackTrace();
} catch (IllegalAccessException e) {
System.err.println("could not access class " + className);
e.printStackTrace();
} catch (ClassNotFoundException e) {
System.err.println("could not find class " + className);
e.printStackTrace();
}
}
cacheMap.put(className, bean);
}
}
return bean;
}
}
3.验证
//这是一个单例注册表
BeanFactory beanFactory = BeanFactory.getInstance();
//获取实例1
Student student1 = (Student) beanFactory
.getBean(Student.class.getName());
//获取实例2
Student student2 = (Student) beanFactory
.getBean(Student.class.getName());
//比较获取到的两个实例
System.out.println(student1.hashCode());
System.out.println(student2.hashCode());
4.结果
spring的工厂模式
todo