dao层的类,service的类和一些工具类交给spring管理是合适的.
实体类不适合交给spring管理
Bean的装配
即Bean对象的创建,由spring创建对象,并给属性赋值,再创建好的对象传递在代码程序的过程.
1. 默认装配方式:spring框架调用类的无参构造方法创建对象
2. 容器中的bean的作用域:由spring创建的对象在容器中的存在范围和可见性.
当通过spring容器创建一个Bean实例时,不仅可以完成bean的实例化,还可以他过scope属性,为bean指定特定的作用域.spring支持5中作用域(4种常用,还一种几乎不用)
- singleton:单态模式,在spring容器中,对象只有一个.
这种模式也是默认模式
对于scope为singleton的单例模式,所有bean对象是在容器被创建时即被装配好了,创建好的对象放入到spring的Map中- prototype:原型模式,每次使用getbean()方法获取同一个<bean/ >的实例时,都将获取一个新对象
对于scope为prototype的原型模式,bean实例是在代码中使用该bean实例时(即执行getbean方法时)才进行装配的
优点是不占内存,缺点是获取对象的速度慢
对于scope为以下两种的只有在web应用中使用spring时,该作用域才有效
- request:在同一个请求中,会产生一个新对象,
不同的请求会产生不同的对象- session:一个会话产生一个对象,不同会话对象不同.
定制bean的生命始末
可以为bean定制初始化后的生命行为,和销毁前的生命行为
自定义方法参与到spring创建和销毁对象的过程中
首先,这些方法需要在bean类中事先定义好:是方法名随意的无参数的public void 方法
其次,在配置文件的bean标签中增加如下属性(告诉spring两个方法的存在):
init-method:指定初始化方法的方法名
- 可以把要在构造方法中完成的功能放在这里面去做,如给属性赋值,初始化其他对象
destroy-method:指定销毁之前执行方法的方法名
清除对象,释放内存等操作
基于XML的DI(Dependency Injection依赖注入)
spring利用依赖注入给属性赋值 注入就是赋值的意思
DI的两种语法方式
- 在XML配置文件中通过标签和属性,完成给对象属性的赋值
- 通过注解的方式来完成对象创建和属性赋值
通过配置文档
- 设值注入(主要注入方式,掌握):调用java类的setter方法给属性赋值
简单类型:spring中把String和java基本数据类型,称为简单类型. 可直接赋值
简单类型的设值注入:
< bean id=“xx” class=“yyy”>
< property name=“属性名” value=“简单类型的属性值”/>
< property name=“属性名” value=“简单类型的属性值”/>
…
< /bean>
引用类型的设值注入:
1)语法一:使用ref作为属性
< bean id=“xx’” class=“yyy”>
< property name=“属性名” ref=“传进bean的id” />
< /bean>
2)语法二:使用ref作为子标签
< bean id=“xx’” class=“yyy”>
< property name=“属性名” >
< ref bean=“传进bean对象的id” />
< /property>
< /bean>
- 构造注入(理解):调用类的有参数构造方法,在创建对象的同时构造方法给属性赋值
语法:使用标签< constructor-arg>表示构造方法参数
一个构造方法的参数对应一个< constructor-arg>标签
在标签中使用以下属性:
1)name:构造方法的形参名.2)index:表示构造方法参数的位置,从0开始(二选一使用)
index属性可以不写,但参数顺序一点要与构造方法参数顺序对应.
相比与index, name用的稍微多一些,
value:简单类型参数的值
ref:引用类型参数的值
具有集合性质的属性注入(掌握)
如 数组,List,Set,Map等集合
public class MyCollections {
private String [] myStr;
private List<Student> myList;
private Set<String> mySet ;
private Map<String, Integer> myMap;
//Properties类型也是Key-Value的结构,但key-value必须都是string类型
private Properties myprop;
public void setMyStr(String[] myStr) {
this.myStr = myStr;
}
public void setMyList(List<Student> myList) {
this.myList = myList;
}
public void setMySet(Set<String> mySet) {
this.mySet = mySet;
}
public void setMyMap(Map<String, Integer> myMap) {
this.myMap = myMap;
}
public void setMyprop(Properties myprop) {
this.myprop = myprop;
}
@Override
public String toString() {
return "MyCollections [myStr=" + Arrays.toString(myStr) + ", myList=" + myList + ", mySet=" + mySet + ", myMap="
+ myMap + ", myprop=" + myprop + "]";
}
}
在XML中
什么类型的属性,就用什么类型的子标签
集合中是简单类型就用value标签,是对象类型就用ref标签’
对于复杂类型的集合也是如此规则,如List< Map< String, String>>
<bean id="myCollections" class="com.ba04.MyCollections">
<!-- Array<String>数组类型 -->
<property name="myStr">
<array>
<value>浦东新区</value>
<value>松江区</value>
</array>
</property>
<!-- List<Student> -->
<property name="myList">
<list>
<ref bean="myStudent"/>这里是学生对象的bean的id
<ref bean="myStudent1"/>
</list>
</property>
<!-- Set<String> -->
<property name="mySet">
<set>
<value>北京</value>
<value>上海</value>
<value>广州</value>
</set>
</property>
<!-- Map<String,Integer> -->
<property name="myMap">
<map>
<entry key="weight" value="80"/>
<entry key="height" value="180"/>
</map>
</property>
<!-- Properties<String,String> -->
<property name="myprop">
<props>
<prop key="tel">010-2334343</prop>
<prop key="phone">123333348989</prop>
</props>
</property>
</bean>
对于引用类型属性的自动注入(理解,不常用)
对于引用类型属性的注入,也可不在配置文件中显示的注入,可以通过< bean/>标签设置autowire属性值,为引用类型属性进行隐式自动注入(默认情况下是不自动注入的).根据自动注入判断标准的不同,可以分为两种
byName:根据名称自动注入
java类中引用类型的属性名和xml配置文件中的< bean>中的id名称一样,且数据类型一致.这样的bean对象能赋值给引用类型
<bean id="myStudent" class="com.ba02.Student" autowire="byName">
<property name="name" value="张三" />
<property name="age" value="22"/>
<property name="sex" value="男"/>
<!-- <property name="mySchool" ref="myXueXiao"/> -->
</bean>
<bean id="mySchool" class="com.ba02.School">
<property name="name" value="清华大学"/>
<property name="address" value="北京市海淀区"/>
</bean>
byType:根据类型自动注入
java类中引用类型的数据类型和xml配置文件中< bean>的class属性值是同源关系的,这样的bean对象能够赋值给引用类型
同源关系:
- java类中引用类型的数据类型和< bean>的class是一样的
- java类中引用类型的数据类型和< bean>的class是父类和子类的关系
- java类中引用类型的数据类型和< bean>的class是接口和实现类的关系
但这样的同源的被调用bean只能有一个.多于一个,容器就不知道该匹配哪一个了.
为应用指定多个spring配置文件(掌握)
在实际应用里,随着应用规模的增加,系统中Bean数量也大量增加,导致配置文件变得非常庞大臃肿,为了避免这种情况的发生,提高配置文件的可读性和可维护性,可以将Spring配置文件分解成多个配置文件.
- 平等关系的配置文件(这种用的不算多,用的多的是下面的一种)
将配置文件分解为地位平等的多个配置文件,并将所有配置文件的路径定义为一个String数组,将其作为容器初始化参数出现,其将与可变参的容器构造器匹配
String configLocation="com\\ba03\\spring-student.xml";
String configLocation2="com\\ba03\\spring-school.xml";
ApplicationContext ctx= new ClassPathXmlApplicationContext(configLocation,configLocation2);
- 包含关系的配置文件(掌握,用的比较多)
各配置文件中有一个总文件,总配置文件将各其他子文件通过< import/>的resource属性引入,在java代码中只需要使用总配置文件对容器进行初始化即可.
注意路径中的classpath:
<import resource="classpath:com/ba03/spring-school.xml" />
<import resource="classpath:com/ba03/spring-student.xml" />
在包含关系的配置文件中,还可以使用通配符*,表示0个或多个字符
注意事项:总的文件名称不能包含在通配符的范围内,total.xml不能叫做spring-total.xml,
不然会加载自身,进入加载死循环.
<import resource="classpath:com/ba03/spring-*.xml" />
包含了上面的两个文件,使用起来更加简便
基于注解的DI
对于DI使用注解,将不再需要在Spring配置文件中声明bean实例
spring中使用注解,需要在原有spring运行环境基础上再做一些改变,完成以下三个步骤:
- 带入AOP的jar包,因为注解的后台实现用到了AOP编程
spring-aop.jar - 需要更换配置文件头,即添加相应的约束
约束在%SPRING_HOME%\docs\spring-framework-reference\html\xsd-cofiguration.html文件中.
spring-context.xsd - 需要在spring配置文件中配置组件扫描器,用于在指定的基本包中扫描注解
定义Bean的注解@Component(掌握)
@Component:创建对象,默认创建的是单例对象
属性:value,表示对象的id
位置:在类的上面,表示创建该类的对象
@Component(value = “myStudent”)等同于
< bean id=“myStudent” class=“com.ba01.Student”/>
框架如何知道注解的存在呢?
我们要在配置文件中声明组件扫描器,指定注解所在的包名
< context: component-scan base-package="" />
component-scan标签叫做组件扫描器(组件指的是java对象)
base-package:指定注解所在的包名,框架会扫描这个包和子包的类的注解
@Component(value = “myStudent”)
//当属性只用到value时可以省略value
@Component( “myStudent”)
//不指定对象的名称时,由框架生成默认的名称:类名的首字母小写
@Component //生成的对象是student(类名为Student时)
和@Component功能相同的其他注解:
- @Repository:放在Dao层实现类的上面,创建Dao对象
- @Service:放在Service层的实现类上面,创建Service对象
- @Controller:放在处理器类的上面,创建控制对象
未完…