Chinaunix首页 | 论坛 | 博客
  • 博客访问: 167840
  • 博文数量: 20
  • 博客积分: 317
  • 博客等级: 二等列兵
  • 技术积分: 809
  • 用 户 组: 普通用户
  • 注册时间: 2012-05-05 18:37
文章分类

全部博文(20)

文章存档

2014年(1)

2013年(5)

2012年(14)

我的朋友

分类: Java

2013-04-07 22:52:40

1,spring是一个开源的控制反转(IOC:Inversion of Control)和面向切面(AOP)的容器框架
控制反转就是应用本身不负责依赖对象的创建及维护,依赖对象的创建及维护是由外部容器负责的。这样控制权有应用转移到了外部容器,控制权的转移就是所谓反转
依赖注入(Dependency Injection):在运行期,由外部容器动态地将依赖对象注入到组件中
spring的优点:
(a)降低组件之间的耦合度,实现软件各层之间的解耦合。
(b)可以使用容器提供的众多服务:事务管理服务,消息服务等等。
(c)容器提供单例模式的支持,开发人员不需要自己写代码。
(d)容器提供了AOP技术,利用它很容易实现权限的拦截,运行期间监控等功能。
(e)提供了很多的辅助类,JdbcTempelet
(f)支持主流框架
轻量级:根据打开的服务多少来判断,spring默认打开核心服务是轻量级的,如果spring打开了所有服务就变成重量级的了,EJB默认打开所有的服务是重量级的
2,spring实现的基本原理:
(1)用dom4j解析配置文件(在构造函数中):将配置文件中的bean解析成一个对象(里面含有id和class,list集合(集合中放property,里面含有属性name,ref,value)),遍历节点,创建bean对象,把id和clazz放进对象,在遍历property,把property放在集合中,然后把所有bean对象放在list集合中
(2)创建bean对象:解析完之后实例化对象,遍历bean集合,将id作为键,使用class的字符串和反射机制创建对象实例,都放在map中
(3)注入对象:遍历bean集合list,根据id查找map得到bean对象,根据bean得到property集合,在遍历property集合,如果是含有ref,注入对象,如果是含有value使用commons-beanutils的jar包自动将字符串转为基本数据类型
在写一个getBean方法得到对象的,使用的时候,使用传id得到对象
3,spring的IOC开发
(1)添加jar包
俩个必须的包:(dist)spring.jar,(lib\jakarta-commons)commons-logging.jar
使用aop的时候:(lib\aspectj)aspectjrt.jar,aspectjweaver.jar
使用连接池的时候:(lib\jakarta-commons) commons-pool.jar, commons-dbcp.jar
(log4j) log4j-1.2.15.jar
使用注解时:lib/j2ee/common-annotations.jar
(2)注入的方式
使用构造器注入:


使用setter注入
自动装配注入:不建议使用,自动装配可能出现问题,因为有的不想装配进去,结果都装配进去了。
使用注解注入
(3)bean的作用域:单例和原型
Bean的生命周期:先进行实例化,在进行初始化,最后是销毁

bean的实例化和销毁:
实例化:默认是单例,在容器实例化时(解析beans.xml文件)就进行实例化对象
当作用域是原型,在调用getBean方法的时候才进行实例化
当是单例时,如果想要延迟对象的初始化使用属性lazy-init="true"

实例化中的的初始化和销毁方法:
上面进行先实例化在初始化,销毁一般是由垃圾回收器实现
初始化方法在原型中,每次创建一个对象都会调用init方法,但destroy方法在原型中是不调用的,一般init和destroy不和原型一起用

实例化bean的三种方式:
最常用的一种
静态工厂
 

实例工厂
 
 
 
 
 
 
(4)注入集合:Set,List,properties,Map

 
    第一个
    第二个
 


 
    第一个
    第二个
 


 
    value1
    value2
 


 
   
   
 

测试的时候:
实例化spring容器,最好的方式是采用相对路径:
ApplicationContext ctx = new ClassPathXmlApplicationContext(new String[]{"beans.xml"});
ApplicationContext ctx = new ClassPathXmlApplicationContext(“XML的名称”);
得到Bean对象PersonService service = (PersonService)ctx.getBean("personService(Bean中的id的值)“);
(5)BeanFactory是IOC的最顶层的接口,在第一次getBean时才会进行创建对象,在启动beanFactory的时候必须含有一种日志框架,否则启动报错,我们使用Log4j
BeanFactory和ApplicationContext另一个最大的区别是:后者会利用java反射机制自动识别出配置文件中定义的BeanPostProcessor等三个接口,而前者需要在代码中通过手工调用addBeanPostProcessor()方法进行注册
4,springAOP
(1)AOP术语:
 (a)连接点:对哪个方法进行拦截,这些方法就是连接点(拦截到的点)
 (b)通知(增强):织入到目标连接点上的一段程序代码
 在方法前调用的通知:前置通知
 放在方法执行后:后置通知
 出现异常执行的是:例外通知
 无论是否异常都执行的:最终通知
 (c)目标对象:增强逻辑的织入目标类
 (d)织入:将切面应用到目标对象并导致代理对象创建的过程叫织入
 (e)引入(Introduction)在不修改代码的前提下,引入可以再运行期动态的强组成
 (g)切入点:对那些连接点进行拦截的定义
(2)(a)使用JDK动态代理时,必须让被代理类实现接口,面向接口编程
代理实现InvocationHandler接口
public Object createProxy(Object target){
  this.target=target;
  return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
 }

public Object invoke(Object proxy, Method method, Object[] args)
   throws Throwable {
  System.out.println("开启事务...");
  Object value = method.invoke(target, args);//回调被代理对象中的方法
  System.out.println("提交事务...");
  return value;
 }

(b)Cglib实现的动态代理,被代理类不用实现接口
代理实现MethodInterceptor接口
cglib创建的代理实际上是继承了目标类,对目标类中所有的非final方法进行覆盖
public Object createProxy(Object target){
  this.target=target;
  Enhancer enhancer = new Enhancer();
  //设置被代理类
  enhancer.setSuperclass(target.getClass());
  //设置回调函数
  enhancer.setCallback(this);//当调用被代理目标中方法,intercept会被自动调用
  return enhancer.create();//通过字节码产生代理对象
 }

public Object intercept(Object proxy, Method method, Object[] args,
   MethodProxy methodProxy) throws Throwable {
  System.out.println("开启事务...");
  Object value = method.invoke(target, args);//回调被代理目标中的方法
  System.out.println("提交事务....");
  return value;
 }
AOP应用:

   
     
     
   
   
   
   
     
     
  
      
     
   
   
    
     
     
     
   

阅读(3357) | 评论(1) | 转发(1) |
给主人留下些什么吧!~~

lifestyle_m1k2013-04-12 18:03:56

不错,总结性很强。