Spring 实例入门

来源:互联网 发布:淘宝下拉词提取工具 编辑:程序博客网 时间:2024/05/19 17:51

Spring 实例入门

本文结合实例理解解容器,DIIOC,耦合,解耦等Spring所涉及的概念,同时了解Spring的最基本也是最核心的使用方法。

1.  Spring容器

Spring容器负责对象的实例化,对象生命周期的管理,Spring管理的对象称之为Bean

例如有Soldier类需要交由Spring容器管理,我们先编写类

package com.hb;

publicclass Soldier {

    private Stringname;

    publicString getName() {

       returnname;

    }

    publicvoid setName(String name) {

       this.name = name;

    }

}

Spring配置文件中添加如下配置

<bean id="s1"class="com.hb.Soldier"></bean>

初始化Spring容器

publicclass Test {

    publicstaticvoid main(String[] args) {

ApplicationContext context = new

ClassPathXmlApplicationContext("applicationContext.xml");

    }

}

Spring容器中取得对象实例

       Soldier s1 = (Soldier) context.getBean("s1");

Spring默认使用单例的方式创建对象。可以通过修改<bean>的配置改变成其它创建方式。这个属性为Scope,称之为作用域或生命周期,它的值为singleton(单例,默认值),prototype(每次产生一个新的实例)等。

   <beanid="s1"class="com.hb.Soldier"scope="prototype"></bean>

 

2.  注入方式有setter注入,构造注入方式,接口注入(不需掌握)。建议多使用Setter注入方式。

Setter注入

Soldier类中有一个属性name,如何在创建Soldier的时候使name的值变为”RANBO”?

配置如下:

<bean id="s1" class="com.hb.Soldier">

<property name="name" value="RANBO"/>

</bean>

这样创建的Soldier对象的name属性就有值了,测试代码:

publicstaticvoid main(String[] args) {

ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

Soldier s1 = (Soldier) context.getBean("s1");

System.out.println(s1.getName());

}

 

构造注入

我们先修改下Soldier类,给它添加一个构造方法:

package com.hb;

publicclass Soldier {

    private Stringname;

 

    public Soldier(String name) {

       this.name = name;

    }

 

    public String getName() {

       returnname;

    }

}

配置如下:

<bean id="s1" class="com.hb.Soldier">

<constructor-arg value="RANBO"></constructor-arg>

</bean>

测试结果同上。

 

3.  依赖

A对象使用了B对象的方法,AB产生依赖,称之为A依赖B。下面的例子中Soldier类依赖HandGun类。

package com.hb;

/**

 *士兵类

 */

publicclass Soldier {

    /**

     *打仗

     */

    publicvoid fight(){

       HandGun handGun = new HandGun();

       handGun.killEnemy();

    }  

}

 

package com.hb;

/**

 *手枪类

 */

publicclass HandGun {

    /**

     *手枪杀敌

     */

    publicvoid killEnemy(){

       System.out.println("手枪杀敌");

    }

}

HandGun发生变化时,必然导致Soldier必须做相应修改,同时,当Soldier需要使用OtherGun时也必须重新编写代码,导致代码重用度不高。

 

当对象之间的依赖关系很强时(耦合),会使程序代码死板,不利于后期的维护和扩展。降低对象之间的依赖关系称之为解耦。Spring能够很好的解决这一问题。

 

4.  控制反转Inversion of Control,简称IOC)和依赖注入(Dependence Inject简称DI)

我们运用Springsetter注入方式解决HandGunSoldier的耦合问题。修改Soldier的代码,将HandGun定义为Soldier的属性并提供setter方法:

package com.hb;

/**

 *士兵类

 */

publicclassSoldier {

    private HandGunhandGun;

   

   

    publicvoid setHandGun(HandGun handGun) {

       this.handGun = handGun;

    }

    /**

     *打仗

     */

    publicvoid fight(){

       handGun.killEnemy();

    }  

}

配置如下

<bean id="s1"class="com.hb.Soldier">

<propertyname="handGun">

<ref bean="handgun"></ref>

</property>

</bean>

<bean id="handgun"class="com.hb.HandGun"></bean>

到这里,我们已经降低了HandGunSoldier的部分依赖关系,至少在Soldier中不用再自己去实例化HandGun了。然而并没有彻底解决问题,Soldier中仍然可以看到HandGun类,因此我们使用接口进一步改进代码:

package com.hb;

/**

 *武器接口

 */

publicinterface Weapon {

    /**

     *杀敌

     */

    void killEnemy();

}

package com.hb;

/**

 *手枪类

 */

publicclass HandGunimplementsWeapon{

    /**

     *手枪杀敌

     */

    publicvoidkillEnemy(){

       System.out.println("手枪杀敌");

    }

}

package com.hb;

/**

 *士兵类

 */

publicclass Soldier {

    private Weaponweapon;

   

   

    publicvoid setWeapon(Weapon weapon) {

       this.weapon = weapon;

    }

    /**

     *使用武器打仗

     */

    publicvoid fight(){

       weapon.killEnemy();

    }  

}

配置如下

<beanid="s1"class="com.hb.Soldier">

<propertyname="weapon">

<ref bean="handgun"></ref>

</property>

</bean>

<bean id="handgun"class="com.hb.HandGun"></bean>

测试:

ApplicationContext context = new

ClassPathXmlApplicationContext("applicationContext.xml");

Soldier s1 = (Soldier) context.getBean("s1");

s1.fight();

至此,我们使用Spring很好的解决了HandGunSoldier的耦合问题。Soldier类中再也看不到HandGun的踪影了,Soldier只依赖于接口,而最终Soldier还是使用了HandGun,这是为什么呢?Spring在这里管理了单个的对象,也管理了对象之间即SoldierHandGun的依赖关系。原本是由Soldier控制HandGun的实例化的,转变为由Spring容器来控制,这里发生了控制权的转移,这就是控制反转Inversion of Control,简称IOC)。当Soldier需要HandGun时,Spring会自动将HandGun对象注入给Soldier,这就是依赖注入了。

 

 

看一下你是否已经有所领悟了:

假如“手枪“已经不满足“士兵”的需要,我们需要将“手枪”更换为更先进的“机枪”,你的程序如何编写呢?自己试一下吧!!

 

 

 

 

spring2.0常见异常

2009-04-06 19:50:51|  分类:Spring |  标签: |字号大中小 订阅

1Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory at org.springframework.util.ClassUtils.<clinit>(ClassUtils.java:67)   at org.springframework.core.io.DefaultResourceLoader.<init>(DefaultResourceLoader.java:52) at org.springframework.context.support.AbstractApplicationContext.<init>(AbstractApplicationContext.java:184) at org.springframework.context.support.AbstractRefreshableApplicationContext.<init>(AbstractRefreshableApplicationContext.java:80) at org.springframework.context.support.AbstractXmlApplicationContext.<init>(AbstractXmlApplicationContext.java:58)   at
需要加上:commons-logging.jar log4j-1.2.11.jar

2Exception in thread "main" org.springframework.beans.factory.BeanDefinitionStoreException: Unexpected exception parsing XML document from class path resource [text.xml]; nested exception is java.lang.NoClassDefFoundError: org/aspectj/weaver/reflect/ReflectionWorld$ReflectionWorldException
Caused by: java.lang.NoClassDefFoundError: org/aspectj/weaver/reflect/ReflectionWorld$ReflectionWorldException
    at java.lang.Class.forName0(Native Method)

需要加上:aspectjweaver.jar

3Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'logBean' defined in class path resource [text.xml]: Initialization of bean failed; nested exception is org.springframework.aop.framework.AopConfigException: Cannot proxy target class because CGLIB2 is not available. Add CGLIB to the class path or specify proxy interfaces.
Caused by: org.springframework.aop.framework.AopConfigException: Cannot proxy target class because CGLIB2 is not available. Add CGLIB to the class path or specify proxy interfaces.
需要加上:cglib-2.1.3.jar


4Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'logBean' defined in class path resource [text.xml]: Initialization of bean failed; nested exception is java.lang.NoClassDefFoundError: org/objectweb/asm/Type
Caused by: java.lang.NoClassDefFoundError: org/objectweb/asm/Type
    at net.sf.cglib.core.TypeUtils.parseType(TypeUtils.java:180)
需要加上:asm.jar
转载:http://pengchua.javaeye.com/blog/142879

5CGLIB Enhancement failed: com.bowen.domain.Schools
java.lang.NoSuchMethodError: org.objectweb.asm.ClassVisitor.visit(IILjava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)V
at net.sf.cglib.core.ClassEmitter.begin_class(ClassEmitter.java:77)
at net.sf.cglib.core.KeyFactory$Generator.generateClass(KeyFactory.java:173)
at net.sf.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:25)
解决:由于不同版本让我想到了可能会因为其它三方包是不同版本引起的最新的MyEclipse,所以里面的Hibernate也是最新的3.1(它里面还带有一个3.0版本的)
删除多余的包 Hibernate3.1现象2
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in resource [/WEB-INF/dataAccessContext-hibernate.xml] of ServletContext: Instantiation of bean failed; nested exception is java.lang.NoClassDefFoundError: javax/transaction/TransactionManager
java.lang.NoClassDefFoundError: javax/transaction/TransactionManager

原因:缺少jta.jar

6.Unexpected exception parsing XML document from class path resource [exer/applicationContext.xml]; nested exception is java.lang.SecurityException: class "org.springframework.beans.factory.support.GenericBeanDefinition"'s signer information does not match signer information of other classes in the same package
Caused by: java.lang.SecurityException: class "org.springframework.beans.factory.support.GenericBeanDefinition"'s signer information does not match signer information of other classes in the same package

原因:jar包冲突,spring.jarspring-core.jar冲突
解决:保留spring-core.jar,spring-web.jar,spring-context.jar

 

 

原创粉丝点击