Spring简化配置的操作
零、复习
- IOC控制反转, 之前是通过new创建对象 , IOC是由Spring容器创建对象 , 需要用时getBean获取 。
- 导入约束文件
- 获取对象两种方式 : 通过ID , 通过class获取
- 创建对象的四中方式
- 构造方法
- 静态工厂
- 实例工厂
- Spring工厂
- scope 控制单例多例
- lazy-init 懒加载 默认情况是单例不懒加载
- 对象的生命周期 init-method dostory-method
- DI
- set 必须要有set方法
- 构造方法 必须要有对应的构造方法
一、Parent和abstract标签
parent指定父类是谁 , 如果需要获取父类中自动注入的值 , 必须加上此属性 。
/** * 用来测试parent标签 * 简化数据源的配置 */ protected DataSource dataSource; public void setDataSource(DataSource dataSource) { this.dataSource = dataSource; } 子类中的代码 ProductDaoImpl public class ProductDaoImpl extends BaseDao implements ProductDao{ /*private DataSource dataSource; public void setDataSource(DataSource dataSource) { this.dataSource = dataSource; }*/ @Override public void add() { dataSource.getConn(); System.out.println("添加商品"); } } public class UserDaoImpl extends BaseDao implements UserDao { /* private DataSource dataSource; public void setDataSource(DataSource dataSource) { this.dataSource = dataSource; } */ @Override public void add() { dataSource.getConn(); System.out.println("添加用户"); } } <?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="datasource" class="datasource.DataSource"></bean> <bean id="baseDao" class="dao.BaseDao"> <property name="dataSource" ref="datasource"></property> </bean> <!--parent配置的形式指明子父级关系 --> <bean id="userDao" class="dao.UserDaoImpl" parent="baseDao"></bean> <bean id="productDao" class="dao.ProductDaoImpl" parent="baseDao"></bean> </beans>
- abstract : 如果bean标签加了此属性 , 值为true , 则Spring容器不会实例化这个bean。
二、autowire属性
- 自动注入
- 只能自动注入自定义对象的属性
两种方式:
- byNmae:原理:通过属性名进行自动注入 , 会找到属性的set方法 , 去掉set后首字母小写后得到属性名作为id查找对象bean标签的id
byType: 通过类型进行自动注入 , 找到注入 , 找不到注入null ,找到多个报错(注意 , bean的class是唯一的 , 否则系统不知道是哪个bean)
<!-- 使用autowire属性标签 自动进行装配 byName:通过属性名称找到对象的bean 查找对象中所有的set方法 setStudent ==> student属性 ==>根据属性查找对象的bean的id byType:通过类型找到对应的bean 查找对象中的所有set方法 setStudent ==> 参数是什么类型 ===根据类型查找class属性 --> <bean id="person" class="bean.Person" autowire="byType"></bean>
默认的自动注入
如果需要注入的配置比较多时 , 可以在beans标签中同一配置默认的注入方式 beans中添加 default-autowire=“byName” <bean id="person" class="bean.Person" autowire="default"></bean>
三、属性注解
导入约束文件 后开启注解功能
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" 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-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd"> <!--启用注解功能 --> <context:annotation-config/> </beans>
给属性添加注解
@autowire
属性自动注入 , 实体类中在属性上加上@Autowire , 如果需要指定名称则在再加一行@Qualifier(value=”XXX”)
public class Person{ @Autowire @Qulifier(value="xxx") private Dog dog; }
- 原理
- 首先自动获取属性的名称去Spring容器中找
- 如果方案一找不到 , 则自动获取属性的class去Spring容器中找 ,
- 如果还找不到并且声明类型为接口 , 则会去Spring容器找中接口唯一的实现类 。 如果该接口有多个实现类则会报错。
@Resource
- 与@Autowire注解的作用一样都是自动注入 , 注入规则也一样 。 但是在聚合工程中不起作用
- 如果需要指定名称则用@Resource(name=”xxx”)
- 使用注解后不需要在类中添加Set方法。
- 使用注解使配置文件更加简单 , 编程更加快速
四、类的注解
- 我们的类交给spring容器来管理,就会写一个bean,但是如果我们的类很多,必然会造成配置文件的冗长。有没有更好的解决办法呢?
使用扫描机制
<!--使用类扫描器 包含了属性注解所以写一个就可以了 base-package="bean,dao,service"可以写多个包中间用“,”号隔开 不能有空格 --> <context:component-scan base-package="bean,dao,service"/>
- 类扫描机制会自动扫描本包和子包,只要给包路径即可。
- 多个包之间用”,”号隔开不能加空格切记
@Component – 类注解
@Component 或@Component(value="person") public class Person{ }
- 在类上加上@Component标签 , 并且在在ApplicationContext.xml文件中添加扫描器之后,就不用再ApplicationContext.xml文件中配置bean标签了
- 原理:
- 创建容器对象 , 扫描配置文件
- 如果配置文件中有自动扫描的开关 , 则立即扫描对应的包即所有的子包下所有包含@Component的注解(或是其他类注解)的类 ,
- 如果该类没有value=”xx”属性 , 则会把Person类的类名首字母小写为person作为id , class就是全类名 ,生成对应的bean
- 如果有value属性 , 则以value的值作为id生成对应的bean , 其他一致
- 关于类的其他注解
- @Compinent 万能注解
- @Service service层
- @Controller servlet层
- @Reposotory dao层
- 作用是一致的 , 只是便于分层
- 类名转id名的规则**
五、关于注解了解内容
@Component(value="personService")
@Scope(value="prototype") //改为多例
@Lazy //懒加载
public class PersonServiceImpl implements PersonService {
@PostConstruct//使该方法作为这个bean生命周期中的初始化方法 , 在构造函数执行后执行 , 生命周期类型的函数 ,只在bean是单例时起作用 。 bean默认是单例的
public void init(){
System.out.println("这是一个初始化方法");
}
//声生命周期中的销毁方法 , 在Spring容器销毁前执行
@PreDestory
public void destory(){
}
六、关于注解赋值
基本类型赋值
@Value(value="男") private String sex;
读取外部properties文件
${key}
Properties 文件内容
#key = value
name=\u5218\u6631\u6C5F
age=18@Value(value=”${name}”)
private String name;@Value(value=”${age}”)
private int age;
给set、map、list赋值
- 导入相关的约束文件
配置文件的头
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:util="http://www.springframework.org/schema/util" 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-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd"> </beans>
在beans标签中添加
<util:list id="list"> <value>2</value> <value>3</value> <value>4</value> <value>5</value> </util:list> <util:set id="set"> <value>222</value> <value>333</value> <value>444</value> </util:set> <util:map id="map"> <entry key="1" value="包头"></entry> <entry key="2" value="北京"></entry> </util:map> <util:properties id="properties"> <prop key="name">李白</prop> <prop key="age">18</prop> </util:properties>
实体类中获取 注入属性
#{@id}
@Value(value="${name}") private String name; @Value(value="${age}") private int age; @Value(value="#{@list}") private List<Integer> list; @Value(value="#{@map}") private Map<Integer,String> map; @Value(value="#{@set}") private Set<String> set; @Value(value="#{@properties}") private Properties properties;
- 导入相关的约束文件