bean
context
core
三个核心之间的关系已经明确
context 就是ioc容器 维护多bean之间的关系
core 就是context维护bean关系的一个工具类
bean关系 发现、创建、维护、管理
bean是什么 通俗点说就是我们要创建的依赖类
比如 我要实例化一个A类 通常就是 new A()
但是通过 <bean id='a' class='A'>的配置,就给我们做了new的初始化操作
更为复杂的就是,我们在A中需要引用B,或者说我们需要在A中创建一个B,并使用它
A{ B b= new B} 而这种关系,在xml的bean中就可以描述出来,并可以进行维护
而上面的这种关系的具体建立是由core完成的,而core是由context来操作的。
所以 间接的说,bean是有context进行操作管理的,core就是一个干活的
context就是老板,core是打工的,bean就是一个个的产品。多个bean之间的关系,也可以看做多产品之间的相互关系
老板管理所有的产品,而这些产品如何记录和每个产品之间是否有关系,就是context雇佣core去生产bean,记录bean,维护bean的关系记录
此时我们需要这些产品bean,那么如何得到他们呢,这时候我们没有办法越过老板context,直接去偷bean,也没办法吧core这个工人挖过来
那么就只能和老板商谈你需要什么产品,你给我报出具体的产品名字,我去库存里面取。这样就获取到了对应的bean
这样被动的去给老板要,比较恶心,因为我们离不开这样产品,所以就和这家老板长期合作,
让他们知道我们哪些店面(这些店就好比我们的包名,即需要被自动注入的扫描包)需要他们自动配货产品,给我们定制,然后
然后看到指定的店,他就给我们配货
比如 A店需要P01产品,而P01产品又和P02产品又关系,那么老板就得把这两种产品都给我发货过去。
这就是所谓的自动注入 就是<context-scan> 在
扫描注解 和 在xml中配置加载 实现的结果都是一样的
扫描注解,如果指定到包下,那么该包下所有符合的注解都会被做为bean进行管理
即被维护好的bean关系后,在相应得bean中就可以操作注入的其他bean
1 通过扫描包,找到对应注解 @component @Server @Resipostory @Controller 作为bean @Resource @AutoWire() 作为依赖
<context:component-scan package="com.test">
@Server
public class UserServer{
@Resource() //默认byname=‘personServer’
private PersonServer personServer;
@Transactional
public void insert(){
Person p = new Person()
personServer.insert(p);
}
}
2 通过传统的xml 配置 装入容器
<bean id='personServer' class='com.test.PersonServer'>
</bean>
<bean id='' class='com.test.UserServer'>
<property name='personServer' ref="personServer"/>
</bean>
3 所以spring是一个基础形式 对于上面两种配置,第一种更适合用于web项目,而第二种是通用版本
所以spring的最基础jar有三个
1 org.springframework中的三个 ,他们组成了spring的核心骨架
spring-beans
spring-context
spring-core
4 在这三个核心的jar基础之上,后来就延伸出了 spring生态系统的其他产品
----------
------------
spring 的作用 ioc的一个展开复述
spring 的实现原理 大致的实现过程
spring 代码的大志实现原理
spring 如何在实战使用
------反射
在spring的实现中,使用了频繁的反射技术,尤其在注解中
1 这里有很多坑需要注意
在我们通过制定类型获取到相关的实例的时候,我们想要知道该类,以及他内部方法上的注解
那么这时候,我们会通过实例a.getClass()来获取到a的class对象,该class中记录了该类的详细信息
Class clzz = a.getClass();
clazz.getAnnotation(XX.class); //这样就可以获取到该类上添加的指定类型的注解类
2 如果是获取Method或者定义的Filed上的注解,那么这里就会有个坑需要注意
Method[] ms = clzz.getMethods(); //获取方法集合
for(Method m :ms )
{
//此时我们需要思考,在实例m中是否需要获取他的class原始信息,
//即 m.getClass() ,然后在通过 他的clazz.getAnnotation()来后去注解信息呢?
//这样获取是错误的,因为Method的原始定义的,他的class也仅有一份,他是通过具体的实例来记录方法的注解,而不是class中存在该解析的注解
//所以 一定要注意,此时很容易掉进去,
m.getAnnotation(xx.class) //次方法是正确的 ,一定不要使用 m.getClass().getAnnotation()的形式
}
3 同时我们也要注意了,在上面中,我们通过一个实例的getClass可以获取到他的原始类信息,这是一般正常情况下
但是也有通过该方式获取不到的,例如:我们使用@Transactional 注解,该注解定义和一般的注解是一样的,但是
他在spring容器启动完成的时候,就被做了相应的处理,也就是对于@Transactional注解(无论是在方法还是在类上)的类
首先生成了一个动态的代理类,该动态的代理类非原先类的信息,然后根据原始类生成了一个子类。
所以如果想要获取该动态代理类的原始类,那就的获取他父类的class原始信息,
Class sClazz= a.getClass().getSuperclass();
那么就可以通过获取动态代理的父类来处理原始的注解信息