咱们的代码中,常常出现A类调用B类和D类,B类调用C类,D类也调用C类,这叫作依赖,而咱们后期开发中会变更这些依赖,好比D类的实现对C类有所改进,可是B类却不须要使用改进的D类,这时候通常方法只能在D类中把对C类的调用改掉。能够想象,依赖一旦多了以后,修改起来就比较麻烦了。这时候引入Spring框架,它就是用来管理类的。最好建立一个Maven项目,这样只要在pom.xml文件里引入:java
<!-- Spring Core --> <!-- http://mvnrepository.com/artifact/org.springframework/spring-core --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>4.1.4.RELEASE</version> </dependency> <!-- Spring Context --> <!-- http://mvnrepository.com/artifact/org.springframework/spring-context --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.1.4.RELEASE</version> </dependency>
1. 不要觉得这里的版本号无所谓,引入其它的版本号,可能会有莫名其妙的错误。spring
若是不知道什么叫Maven,那么请自行搜索学习。框架
在开发前,我先将一个故事,张3、李四去山上砍柴,张三喜欢用石头作的斧子,李四喜欢用铁作的斧子。很显然,张三和李四的共同点是二者都是人,咱们最好定义一我的的接口,否则哪天王二麻子来了,又要从新写个类多麻烦。一样,也要定义一个斧子的接口,万一哪天换成电锯了呢。学习
人的接口:测试
package com.hengzecn.Spring; public interface Person { public void useAxe(); }
斧子的接口,在接口里面定义了砍这个方法:this
package com.hengzecn.Spring; public interface Axe { public String kan(); }
张三来了:netty
package com.hengzecn.Spring; public class ZhangSan implements Person { public Axe axe; public void setAxe(Axe axe){ this.axe = axe; } public void useAxe() { // TODO Auto-generated method stub System.out.println(axe.kan()); } }
1 张三虽然喜欢用石头斧子,可是他万一想换换斧子呢,咱们从后面能够看到,张三果真想换斧子。code
李四来了:component
package com.hengzecn.Spring; public class LiSi implements Person { public Axe axe; public void setAxe(Axe axe){ this.axe = axe; } public void useAxe() { // TODO Auto-generated method stub System.out.println(axe.kan()); } }
如今实现石头斧子:xml
package com.hengzecn.Spring; public class StoneAxe implements Axe { public String kan() { // TODO Auto-generated method stub return "石头斧子"; } }
铁斧子:
package com.hengzecn.Spring; public class IronAxe implements Axe { public String kan() { // TODO Auto-generated method stub return "铁斧子"; } }
Spring须要一个配置文件,通常放在src文件夹下:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="zhangSan" class="com.hengzecn.spring.ZhangSan"> <property name="axe" ref="stoneAxe" /> </bean> <bean id="liSi" class="com.hengzecn.spring.LiSi"> <property name="axe" ref="ironAxe" /> </bean> <bean id="stoneAxe" class="com.hengzecn.spring.StoneAxe" /> <bean id="ironAxe" class="com.hengzecn.spring.IronAxe" /> </beans>
1. 要注意大小写,通常包名用小写
写个程序测试下:
package com.hengzecn.spring; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class SpringTest { public static void main(String[] args) throws Exception{ ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml"); Person p = (Person) ctx.getBean("liSi"); p.useAxe(); } }
结果以下图:
回过头来看什么叫注入,个人理解就是帮你初始化对象,注入强调的是一个动态过程,也就是写程序的时候不用初始化,运行的时候根据配置文件进行初始化。
若是嫌配置xml烦的话,也能够用Spring的注解,使用注解的时候要注意,配置文件和必定要加上命名空间:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context = "http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> <!-- 该 BeanPostProcessor 将自动对标注 @Autowired 的 Bean 进行注入 --> <context:component-scan base-package = "com.hengzecn.Spring"/> <bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/> <bean id="zhangSan" class="com.hengzecn.Spring.ZhangSan"> </bean> <bean id="liSi" class="com.hengzecn.Spring.LiSi"> </bean> <bean id="stoneAxe" class="com.hengzecn.Spring.StoneAxe" /> <bean id="ironAxe" class="com.hengzecn.Spring.IronAxe" /> </beans>
1. 不要忘了xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"和http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd
2. 自动标注<context:component-scan
base-package = "com.hengzecn.Spring"/>
咱们在张三的实现类中:
package com.hengzecn.Spring; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; public class ZhangSan implements Person { @Autowired @Qualifier(value = "stoneAxe") private Axe axe; public void setAxe(Axe axe){ this.axe = axe; } public void useAxe() { // TODO Auto-generated method stub System.out.println(axe.kan()); } }
1. @Autowired是自动注入,由于有两个Axe类型的bean,因此用@Qualifier区别一下,是使用id为stoneAxe的bean来注入
@Resource可以起到上述一样的效果:
package com.hengzecn.Spring; import javax.annotation.Resource; public class ZhangSan implements Person { @Resource(name="stoneAxe") private Axe axe; public void setAxe(Axe axe){ this.axe = axe; } public void useAxe() { // TODO Auto-generated method stub System.out.println(axe.kan()); } }
1. @Resource注解是javax.annotation.Resource包里面的,注意下运行环境,我用的是JRE 1.8,过小的版本没有这个注解。
从配置文件能够看出,在引入注解以后,配置文件中省略掉了<property></property>
Spring就谈到这里,其它注解不是很难,想了解的,或者想深刻了解的,自行搜索学习。
虽然这一部分没有谈netty,可是Spring是一个基础,咱们能够用Spring来管理netty程序。