捡框架的小男孩--Spring(一)
spring 是一个轻量级(不需要继承啊,实现啊就能使用)的控制反转(IoC)和面向切面的容器框架。本文基于spring 4.1.6导入需要包1.spring-core.jar2.spring-benas.jar3.spring-context.jar4.spring-expression.jar5.commons-logging注:这个不是spring的包而是spring
spring 是一个轻量级(不需要继承啊,实现啊就能使用)的控制反转(IoC)和面向切面的容器框架。
本文基于spring 4.1.6
导入需要包
1.spring-core.jar
2.spring-benas.jar
3.spring-context.jar
4.spring-expression.jar
5.commons-logging
注:这个不是spring的包而是spring依赖的包。(spring开发者调用别人写好的包。如下面的源码)
![Spring源码](https://img-blog.csdn.net/20170424174132241?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdjVfQkFU/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
![Spring模块](https://img-blog.csdn.net/20170424173534078?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdjVfQkFU/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
可见和我们要将核心容器相关的jar导入。(就是上面前四个)
Spring 是模块化的,用到什么导入什么。
控制反正IoC
等同于依赖注入
为了避免对象之间复杂的关系而使得程序高耦合。为了解决这个问题所以有了IoC.
IoC为协调各个组件间的依赖关系,使用动态的注入(可以理解为赋值)从而是的代码低耦合,扩展性更好。
由原先的 new 一个对象,变成现在的容器装配。
代码分析
再经典不过的例子Helloword
新建一个java工程
src 下建立如下 HelloWord javaBean
package Test;
public class HelloWord {
private String content;
public String getContent() {
System.out.println("getcontent way run ..");
return content;
}
public void setContent(String content) {
this.content = content;
System.out.println("setcontent way run ..");
}
public HelloWord() {
System.out.println(" hellowrod constructor run..." +content);
}
public void hello(){
System.out.println(content);
}
}
在src 新建一个 Spring Bean Configuration File 名字为 beansContext.xml(自拟)
<?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">
</beans>
我们要做的就是在<beans></beans> 添加<bean>
<?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">
<!--id:可以理解为容器为我们创建对象的引用 class:一看是全类名,八九不离十是容器使用反射帮我们创建对象(默认当然是找无参构造器所以在没有指定的情况下要有无参构造器) -->
<bean id="helloWord" class="Test.HelloWord">
<!--property 由于对属性赋值 name:跟属性名 value:跟要给的值 -->
<property name="content" value="helloword"></property>
</bean>
</beans>
注:这里在多说几句 property 赋值是通过setXXX来赋值的。在源码中将name 的值拿到通过改变首字母大写再在前面加上set得到方法名去调用方法传入value.(本例中就是 content->Conent->setContent).
写一个测试方法
package Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Main {
public static void main(String[] args) {
ApplicationContext ioc=new ClassPathXmlApplicationContext("beansContext.xml");
HelloWord hw=(HelloWord) ioc.getBean("helloWord");
hw.hello();
}
}
见证奇迹的时刻到了。控制台不仅打印了helloword 和 方法执行时sysout 还有一大片的信息。
正如前面所说的我们为什么要加入logging包 就是spring有调用日志方法。
当我们把
//HelloWord hw=(HelloWord) ioc.getBean("helloWord");
// hw.hello();
这两行注释掉又发现有趣的现象,尽然还执行了 构造器 和set 方法。这是因为 默认情况下ApplicationContext 启动时将实例化所有的singleton bean.
先解释singleton: bean 节点除了 id、 class 还有scope 、factory-bean、factory-method 属性
而这里的singleton 就是scope的属性值 作用就是在容器中共享一个bean 实例。什么意思呢。用代码说明直接一点。
<bean id="helloWord" class="Test.HelloWord" scope="singleton">
<property name="content" value="helloword"></property>
</bean>
先加上scope 属性
package Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Main {
public static void main(String[] args) {
ApplicationContext ioc=new ClassPathXmlApplicationContext("beansContext.xml");
HelloWord hw=(HelloWord) ioc.getBean("helloWord");
HelloWord hw2=(HelloWord) ioc.getBean("helloWord");
System.out.println(hw2==hw);
}
}
结果为true
而如果吧属性值改为 prototype恰恰相反 相同的代码结果为false;
依赖注入
依赖注入的方式:属性注入 构造器注入
属性注入
就是上面我们使用的方法通过 property 来注入
构造器注入
使用<constructor-arg> 能用代码解决的事情绝对不多说。上代码
简单的person bean
package Test;
public class Person {
private String name;
private int age;
private Person parent;
public Person(String name){
this.name=name;
}
public Person(String name,int age){
this(name);
this.age=age;
}
public Person(String name,int age,Person parent){
this(name,age);
this.parent=parent;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Person getParent() {
return parent;
}
public void setParent(Person parent) {
this.parent = parent;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + ", parent=" + parent
+ "]";
}
}
新建一个personContext.xml用于注入(也可以在之前xml文件中写为了清晰重新建了一个)
<?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="son" class="Test.Person" depends-on="father">
<constructor-arg value="张三" index="0"></constructor-arg>
<constructor-arg value="3" type="int"></constructor-arg>
<constructor-arg ref="father"></constructor-arg>
</bean>
<bean id="father" class="Test.Person" lazy-init="true" >
<constructor-arg value="张二" index="0"></constructor-arg>
<property name="parent" ><null/></property>
</bean>
</beans>
看第一个bean 就是使用构造方法备注属性同时也可以发现 Person中没有 无参构造器但是没有错。就是前面说的 默认为无参构造器除非指定 。 这里的指定就是使用 constructor-arg 。
看一下结果
Person [name=张三, age=3, parent=Person [name=张二, age=0, parent=null]]
善于观察的人会发现father不是延迟加载吗 怎么加载了。这里存在依赖关系 son有引用是 father是所以使用到了当然要加载。延迟加载是不会在没有用到的情况下自动加载。而这里使用到了。
还有一点depends-on好像没什么用。是这样的我吗看看结果中 “张二”的parent=null 如果在第二个bean中加上depends-on 则不能为null 了必须要有依赖的bean。
住:null 在这里的写法是上面的写法 另外在补充特殊字符的写法比如要显示> 《![CDATA[hh>]]》(这里由于不能打尖括号就用汉语的双括号代替了)
有时还会遇到给List map set这样的集合赋值 怎么办呢:
<bean id="father" class="Test.Person" lazy-init="true" >
<constructor-arg value="张二" index="0"></constructor-arg>
<property name="parent" ><null/></property>
<property name="list">
<list>
<value>this is list</value>
</list>
</property>
<property name="map">
<map>
<entry>
<key>
<value>this is key</value>
</key>
<value>this is map value</value>
</entry>
</map>
</property>
<property name="set">
<set>
<value>this is set</value>
</set>
</property>
</bean>
bean 属性 补充
刚刚我们看到了scope 属性的应用现在再补充一下其他的属性
1.lazy-init 延迟初始化bean
这不难让我们联想到懒汉式设计模式。当用到的时候在初始话。这样对于一些加载需要耗费大量资源的bean会很有用。
2.depend-on : 依赖的对象不能为null
更多推荐
所有评论(0)