spring基础 - 总结回顾
1 啥是Spring
就是一个框架
啥是框架,就是一个模板,骨架给你了,自己填血肉
这个框架能干啥,IOC和AOP
也是Spring的俩个大核,控制反转+面向切面
目前我能看到的功能,去耦合,不动源代码的基础上修改代码功能
2 IOC
2.1 为什么称为IOC容器
因为spring中的对象都是spring创建的,都存在这个容器里面,通过context上下文,用哪个拿哪个
容器在手,天下我有
2.2 为啥叫控制反转
控制:· 谁来控制生成对象
反转: 之前是程序本身控制,哪一行需要啥功能了,就new啥对象
现在不一样了,控制权交给spring,程序需要啥功能,找spring要对象
总结:程序从主动创建对象,到被动接受对象
2.3 对象的创建
- 用xml的bean标签创建
<bean id class>
<properties ></properties>
</bean>
-
用啥创建的
类的无参构造,然后调用set方法填属性,所以必须有无参构造和set方法
也可以用有参构造,使用
-
怎么获得
context上面问的getBean( )方法,有id对应
- 什么时间生成
xml加载就创建了,能创建几个由scope属性说的算
2.4 命名空间
c空间,p空间,context空间,
这些空间是干啥的,作为一种约束
c是啥,constructor,构造器命名空间
p是啥,p就是properties,属性命名空间
目的是干啥,少写点字。就直接吧p:属性名,作为一个属性,塞到bean标签里面
2.5 注解和xml
一般鼓励用注解进行开发
但是,万一有个类,里面有个属性,是个列表,最好还是用xml的list标签注入
配置文件的好处...输入bean 会有各种提示,注解啥也没有....
3 AOP (重点*)
3.1 代理模式
代理模式可以说是AOP的底层
代理模式其实就是加了一层,千层饼+1
3.2 静态代理
-
你-----中介--------房东(并不想认识你,就只想收房租)
-
抽象角色:一般使用接口或者抽象类来解决(租房接口)
-
真实角色:被代理的角色(房东)
-
代理角色:代理真实角色,代理真实角色后,一般会做一些附属操作(中介,可以附加看房,收租功能)
-
客户:访问代理对象的人(你)
-
缺点:一个真实角色对应一个代理,double代码量
3.3 动态代理
代理类是动态生成的,不是我们直接写好的。
分为两大类
- 基于接口-JDK动态代理 【用这就行】
- 基于类的:cglib
- 基于JAVAssist
需要了解两个类:proxy,invocationHandler
妈的尚硅谷笔记里都记录的东西,一点印象都没有了
Proxy类,就用一个静态方法就行了 newProxyInstance(),他能生成一个代理对象
static object newProxyInstance(ClassLoader ,Class<?>[] interface, InvocationHandler h)
-param
类加载器
增强方法所在的类实现的接口,注意:可以使多个接口[]
实现这个接口Invocationhandler, 创建代理对象,写增强的方法
比较尚硅谷和狂神的两种代理方法,就以租房为例
- 租房接口Rent
public interface Rent {
public void rent();
}
- 房东实现类Host
public class Host implements Rent {
@Override
public void rent() {
System.out.println("房东要出租房子");
}
}
- 狂神动态代理类
public class ProxyInvocationHanderKang implements InvocationHandler {
private Object object;
public void setObject(Object object) {
this.object = object;
}
//生成得到代理类
public Object getProxy(){
return Proxy.newProxyInstance(this.getClass().getClassLoader(),object.getClass().getInterfaces(), this );
}
//处理代理实例,并返回结果
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//动态代理的本质,就是反射
Object res = method.invoke(object,args);
return res;
}
}
- 尚硅谷动态代理类
public class ProxyShangguigu implements InvocationHandler {
//被代理的对象
private Object object;
public ProxyShangguigu(Object o) {
this.object = o;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object res = method.invoke(object);
return res;
}
}
- 测试类
public class Cilent {
@Test
public void testKang(){
//真实角色
Rent rent = new Host();
//代理角色处理程序
ProxyInvocationHanderKang pih = new ProxyInvocationHanderKang();
//通过调用程序处理角色来处理我们要调用的接口对象
pih.setRent(rent);
Rent proxy = (Rent) pih.getProxy();//获得代理类了
proxy.rent();
}
@Test
public void testShangguigu(){
//真实角色
Rent rent = new Host();
//获得代理类
Rent proxyRent = (Rent)Proxy.newProxyInstance(Cilent.class.getClassLoader(), new Class[]{Rent.class}, new ProxyShangguigu(rent));
//用
proxyRent.rent();
}
}
其实一模一样,。一个是把生成代理的过程包装在动态代理实现类里面了,一个是动态代理实现类只包含基本的方法代理功能,生成都代理对象的过程交给需要的地方。
我喜欢狂神的写法
问题:
俩种方法的newProxyInstance放在的地方不一样,那么第一个参数的类加载器也不一样,有影响么
注意:这里就是在用反射来干活,不然你凭啥不改变源代码就能往里面添加功能,就能连对象都不new就操作里面函数
那么反射需要啥,类加载器!
这个类加载器在上面例子里面各自用的newProxyInstance方法所在类的类加载器,换一个行不行? 行!
比如用真实角色的,rent.getClass().getClassLoader(); 或者 Rent.class.getClassLoader() 有区别吗。没区别
3.4 AOP
本文来自博客园,作者:荧惑微光,转载请注明原文链接:https://www.cnblogs.com/yinghuoweiguang/p/16095936.html