Spring-IOC个人笔记
1、简介
Spring是一个开放源代码的设计层面框架,他解决的是业务逻辑层和其他各层的松耦合问题,因此它将面向接口的编程思想贯穿整个系统应用。Spring是于2003 年兴起的一个轻量级的Java 开发框架,由Rod Johnson创建。简单来说,Spring是一个分层的JavaSE/EE full-stack(一站式) 轻量级开源框架。
特点
- 开源免费
- 轻量级、非入侵式(小而美)
- 容器大杂烩,可以整合很多种框架
参考文档连接:
https://docs.spring.io/spring-framework/docs/4.3.9.RELEASE/spring-framework-reference/html/
2、IOC的理解
IOC(控制反转),从字面上感觉神秘,但一个set()
方法却能很好地解释这个概念。不过IOC并不止是set()
。
以下基于dao层和service层之间的关系进行IOC的理解:一般而言,service层由于需要从数据库中获得数据,不可避免地需要通过dao层去访问数据库,这两者之间就形成了关联。对于关联关系的处理,不同的做法就会产生不同的结果,比如下面两种方式,仅仅因为一个set()
方法,产生的效果却大不相同:
方式1
-
dao层
package com.zero.dao; /** * 模拟数据库dao层接口 */ public interface SqlDao { /** * 输出一条信息 */ void getMessage(); }
package com.zero.dao; /** * SqlDao的实现类1---->MySqlDao */ public class MySqlDao implements SqlDao { /** * 实现方法 */ public void getMessage() { System.out.println("MySql的Dao实现"); } }
package com.zero.dao; /** * SqlDao的实现类2---->OracleDao */ public class OracleDao implements SqlDao { public void getMessage() { System.out.println("Oracle的dao实现"); } }
-
service层
package com.zero.service; /** * 关于sql的service层接口 */ public interface SqlService { /** * 用于调用SqlDao层的接口方法,获得消息输出 */ void getMessage(); }
package com.zero.service; import com.zero.dao.MySqlDao; import com.zero.dao.SqlDao; /** * SqlService的实现类 */ public class SqlServiceImpl implements SqlService { //关联一个SqlDao对象并直接初始化MySqlDao对象 private SqlDao sqlDao = new MySqlDao(); public void getMessage() { //调用SqlDao的接口方法获得输出 sqlDao.getMessage(); } }
-
客户端调用层
import com.zero.service.SqlServiceImpl; import org.junit.Test; public class IocTest { @Test public void iocTest(){ //获得service层对象 SqlServiceImpl sqlService = new SqlServiceImpl(); //调用对象获取打印消息的方法 sqlService.getMessage(); } }
-
输出结果
MySql的Dao实现
方式2
-
dao层
dao层的实现依旧和上面一样
-
service层
service层接口和上面的一样
package com.zero.service; import com.zero.dao.MySqlDao; import com.zero.dao.SqlDao; /** * SqlService的实现类 */ public class SqlServiceImpl1 implements SqlService { //关联一个SqlDao对象并初始化为MySqlDao对象 private SqlDao sqlDao = new MySqlDao(); //为关联的对象提供set()方法 public void setSqlDao(SqlDao sqlDao) { this.sqlDao = sqlDao; } public void getMessage() { sqlDao.getMessage(); } }
-
客户端调用层
@Test public void iocTest1(){ //获得service层对象 SqlService sqlService = new SqlServiceImpl1(); //调用对象获取打印消息的方法 sqlService.getMessage(); //给sqlService对象设置其他的SqlDao对象 ((SqlServiceImpl1)sqlService).setSqlService(new OracleDao()); //再调用对象获取打印消息的方法 sqlService.getMessage(); }
-
输出结果
MySql的Dao实现 Oracle的dao实现
对比
方式一,无论进行多少次调用,sqlService.getMessage()
方法的调用只能获得一种dao实现类的输出,因为在编写service层接口实现时,已经将关联的对象绑死了,客户若需要使用其他的dao层实现,只能修改原来代码中绑定的对象。
方式二,由于提供了SqlDao
对象的set()
方法,所以一开始绑定的SqlDao
对象会作为调用的默认对象,在客户需要修改绑定对象时,可以使用set()
方法进行改绑,从而达到不用修改原有代码,仅需在使用的时候进行set()
调用即可。
结论
控制反转,指的是将创建对象的控制权进行反转,不再是在一开始编码时就创建对象并绑定,而是将创建对象的权力交给使用者,让他们决定使用哪种对象。set()方法的注入就是控制反转的实现途径之一。
3、搭建Spring环境
引入相关jar包(实际上需要很多jar包,但
spring-webmvc.jar
会帮我们引入很多依赖jar包)
<dependencies>
<!-- spring-webmvc包,该包会自动去导入其他需要的依赖jar -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.0.RELEASE</version>
</dependency>
<!-- junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
编写环境
- dao层
package com.zero.dao;
/**
* 模拟数据库dao层接口
*/
public interface SqlDao {
/**
* 输出一条信息
*/
void getMessage();
}
package com.zero.dao;
/**
* SqlDao的实现类1---->MySqlDao
*/
public class MySqlDao implements SqlDao {
/**
* 实现方法
*/
public void getMessage() {
System.out.println("MySql的Dao实现");
}
}
package com.zero.dao;
/**
* SqlDao的实现类2---->OracleDao
*/
public class OracleDao implements SqlDao {
public void getMessage() {
System.out.println("Oracle的dao实现");
}
}
- service层
package com.zero.service;
/**
* 关于sql的service层接口
*/
public interface SqlService {
/**
* 用于调用SqlDao层的接口方法,获得消息输出
*/
void getMessage();
}
package com.zero.service;
import com.zero.dao.MySqlDao;
import com.zero.dao.SqlDao;
/**
* SqlService的实现类
*/
public class SqlServiceImpl implements SqlService {
//关联一个MySqlDao对象并直接初始化
private SqlDao sqlDao = new MySqlDao();
//提供set()方法
public void setSqlDao(SqlDao sqlDao){
this.sqlDao = sqlDao;
}
public void getMessage() {
//调用SqlDao的接口方法获得输出
sqlDao.getMessage();
}
}
编写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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--
bean标签相当于new一个对象,只是将该对象托管在spring容器中,要使用时从容器获取即可,
id表示该对象在容器中的唯一标识,class表示要创建的类对象。
property标签相当于调用对象的set()方法,ref用于通过id引用容器中的其他bean对象
-->
<!-- 配置SqlServiceImpl对象 -->
<bean id="sqlService" class="com.zero.service.SqlServiceImpl">
<!--通过ref引用mysqlSqlDao对象-->
<!--<property name="sqlDao" ref="mysqlSqlDao"/>-->
<!--通过ref引用oracleSqlDao对象-->
<property name="sqlDao" ref="oracleSqlDao"/>
</bean>
<!-- 配置MySqlDao对象 -->
<bean id="mysqlSqlDao" class="com.zero.dao.MySqlDao"/>
<!-- 配置OracleDao对象 -->
<bean id="oracleSqlDao" class="com.zero.dao.OracleDao" />
</beans>
使用测试
import com.zero.service.SqlService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class SpringTest {
@Test
public void springTest(){
//获取Spring容器
ApplicationContext context = new ClassPathXmlApplicationContext("application-config.xml");
//通过容器中的id获取bean对象
SqlService sqlService = (SqlService) context.getBean("sqlService");
//调用bean对象的方法
sqlService.getMessage();
}
}
测试结果
<!--通过ref引用oracleSqlDao对象时,输出如下-->
<property name="sqlDao" ref="oracleSqlDao"/>
Oracle的dao实现
<!--通过ref引用mysqlSqlDao对象时,输出如下-->
<property name="sqlDao" ref="mysqlSqlDao"/>
MySql的Dao实现
4、IOC的依赖注入方式
spring中实现IOC(控制反转)的方式主要有以下几种方式,使用类的构造器进行注入、使用类的set方法进行注入、使用命名空间的方式注入(本质上是以上两种注入方式的简化)。构造器注入和set方法注入有其各自的优缺点:
优点 | 缺点 | |
---|---|---|
构造器注入 | 能够在构造对象的时候就给属性赋值,避免了空指针的问题 | 有时候构造的属性过多时,这种注入方式显得麻烦;另外构造注入难以实现后期对象的属性的修改。 |
set注入 | 能够依据需要,只对需要的属性进行注入 | 需要依赖空构造方法;创建对象之初可能有属性没有被赋值,可能出现空指针问题 |
4.1、构造器注入
使用构造器进行注入,要求pojo类必须定义了该构造器,否则无法使用。构造器方式进行注入,有以下三种方式:
搭建测试环境(定义两个pojo类)
- Address类
package com.zero.pojo;
/**
* Address类
*/
public class Address {
//地址详情
private String detail;
//邮箱编码
private String mailCode;
public Address(){
}
public Address(String detail, String mailCode) {
this.detail = detail;
this.mailCode = mailCode;
}
public String getDetail() {
return detail;
}
public void setDetail(String detail) {
this.detail = detail;
}
public String getMailCode() {
return mailCode;
}
public void setMailCode(String mailCode) {
this.mailCode = mailCode;
}
@Override
public String toString() {
return "Address{" +
"detail='" + detail + '\'' +
", mailCode='" + mailCode + '\'' +
'}';
}
}
- User类
package com.zero.pojo;
/**
* User类
*/
public class User {
//姓名
private String name;
//性别
private int gender;
//住址(Address类)
private Address address;
public User() {
}
public User(String name, int gender, Address address) {
this.name = name;
this.gender = gender;
this.address = address;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getGender() {
return gender;
}
public void setGender(int gender) {
this.gender = gender;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", gender=" + gender +
", address=" + address +
'}';
}
}
使用构造参数名的方式进行构造
- 配置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">
<!-- 使用构造参数名进行注入(使用constructor-arg标签进行注入,name代表构造方法参数名) -->
<bean id="user" class="com.zero.pojo.User">
<!-- 基本数据类型和String直接使用value进行赋值 -->
<constructor-arg name="name" value="小明"/>
<constructor-arg name="gender" value="1"/>
<!-- pojo类型,使用ref引用其他bean进行注入 -->
<constructor-arg name="address" ref="address"/>
</bean>
<!-- 创建Address类对象 -->
<bean id="address" class="com.zero.pojo.Address">
<constructor-arg name="detail" value="广州"/>
<constructor-arg name="mailCode" value="123456"/>
</bean>
</beans>
- 测试
@Test
public void constructorByNameTest(){
//获得容器
ApplicationContext context = new ClassPathXmlApplicationContext("applicationConfig.xml");
//获得bean对象
User user = context.getBean("user", User.class);
//输出
System.out.println(user);
}
- 结果
User{name='小明', gender=1, address=Address{detail='广州', mailCode='123456'}}
使用构造参数下标进行构造
- 配置
<?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">
<!-- index代表构造方法的参数索引,其余的和name方式的一样 -->
<bean id="user" class="com.zero.pojo.User">
<constructor-arg index="0" value="小明"/>
<constructor-arg index="1" value="1"/>
<constructor-arg index="2" ref="address"/>
</bean>
<!-- 创建Address类对象 -->
<bean id="address" class="com.zero.pojo.Address">
<constructor-arg name="detail" value="广州"/>
<constructor-arg name="mailCode" value="123456"/>
</bean>
</beans>
- 测试
@Test
public void constructorByIndexTest(){
//获得容器
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
//获得bean对象
User user = context.getBean("user", User.class);
//输出
System.out.println(user);
}
- 结果
User{name='小明', gender=1, address=Address{detail='广州', mailCode='123456'}}
使用构造参数类型进行构造
- 配置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">
<!-- type代表构造方法的参数类型(要使用全限定类型名),其余的和name方式的一样 -->
<bean id="user" class="com.zero.pojo.User">
<constructor-arg type="java.lang.String" value="小明"/>
<constructor-arg type="int" value="0"/>
<constructor-arg type="com.zero.pojo.Address" ref="address"/>
</bean>
<!-- 创建Address类对象 -->
<bean id="address" class="com.zero.pojo.Address">
<constructor-arg name="detail" value="广州"/>
<constructor-arg name="mailCode" value="123456"/>
</bean>
</beans>
- 测试
@Test
public void constructorByTypeTest(){
//获得容器
ApplicationContext context = new ClassPathXmlApplicationContext("beans1.xml");
//获得bean对象
User user = context.getBean("user", User.class);
//输出
System.out.println(user);
}
- 结果
User{name='小明', gender=0, address=Address{detail='广州', mailCode='123456'}}
小结
- 提倡使用前两种方式,第三种可能会出现多个参数类型相同的情况。
4.2、set注入
使用set方法进行注入,要求pojo类必须提供空构造器,否则无法使用。set方式进行注入,主要针对以下几种类型进行注入:
- 基本类型(以及String)
- pojo类型
- 数组
- List
- set
- map
- properties ( 指Java.util.Properties )
搭建测试环境(创建一个实体类, 包含各种属性)
package com.zero.pojo;
import java.util.*;
/**
* Student类
*/
public class Student {
//姓名
private String name;
//住址(Address类对象)
private Address address;
//爱好(数组类型)
private String[] hobbies;
//书籍(List集合)
private List<String> books;
//游戏(set集合)
private Set<String> games;
//身份卡(Map集合)
private Map<String, String> card;
//信息(Propertirs对象)
private Properties info;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
public String[] getHobbies() {
return hobbies;
}
public void setHobbies(String[] hobbies) {
this.hobbies = hobbies;
}
public List<String> getBooks() {
return books;
}
public void setBooks(List<String> books) {
this.books = books;
}
public Set<String> getGames() {
return games;
}
public void setGames(Set<String> games) {
this.games = games;
}
public Map<String, String> getCard() {
return card;
}
public void setCard(Map<String, String> card) {
this.card = card;
}
public Properties getInfo() {
return info;
}
public void setInfo(Properties info) {
this.info = info;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", address=" + address +
", hobbies=" + Arrays.toString(hobbies) +
", books=" + books +
", games=" + games +
", card=" + card +
", info=" + info +
'}';
}
}
配置文件
<?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">
<!-- 使用set方式配置bean,与构造器的方式不同,内部标签使用property -->
<bean id="student" class="com.zero.pojo.Student">
<!-- 基本数据类型以及String类型配置,name代表set方法后的名称,value代表赋的值 -->
<property name="name" value="小强"/>
<!-- 引用bean对象进行配置,name代表set方法后的名称,ref代表通过bean的id进行引用 -->
<property name="address" ref="address"/>
<!-- 数组类型配置,内部使用array标签进行配置,value代表数组元素的值(也可以使用ref等其他的配置引用对象等等) -->
<property name="hobbies">
<array>
<value>篮球</value>
<value>足球</value>
<value>羽毛球</value>
</array>
</property>
<!-- list类型配置, 内部使用list标签,其余的配置和数组的一样 -->
<property name="books">
<list>
<value>水浒传</value>
<value>三国演义</value>
<value>红楼梦</value>
<value>西游记</value>
</list>
</property>
<!-- set类型配置, 内部使用set标签,其余的配置和数组的一样 -->
<property name="games">
<set>
<value>LOL</value>
<value>BOB</value>
<value>COC</value>
</set>
</property>
<!--
map类型配置, 内部使用map标签,
map标签内部使用一个entry标签代表一个键值对,entry标签的key代表键, value代表值
-->
<property name="card">
<map>
<entry key="123456" value="132456798456456"/>
</map>
</property>
<!--
Properties类型配置, 内部使用props标签,
map标签内部使用一个prop标签代表一个键值对,prop标签的key代表键, 键的值必须写在prop标签体内
-->
<property name="info">
<props>
<prop key="age">18</prop>
<prop key="height">179</prop>
</props>
</property>
</bean>
<!-- 创建Address类对象 -->
<bean id="address" class="com.zero.pojo.Address">
<constructor-arg name="detail" value="广州"/>
<constructor-arg name="mailCode" value="123456"/>
</bean>
</beans>
测试
@Test
public void setTest(){
//获得容器
ApplicationContext context = new ClassPathXmlApplicationContext("student.xml");
//获得bean对象
Student student = context.getBean("student", Student.class);
//输出
System.out.println(student);
}
结果
Student{
name='小强',
address=Address{detail='广州', mailCode='123456'},
hobbies=[篮球, 足球, 羽毛球],
books=[水浒传, 三国演义, 红楼梦, 西游记],
games=[LOL, BOB, COC],
card={123456=132456798456456},
info={height=179, age=18}
}
注意
- property标签内的name属性指的是setXxx()方法后的Xxx首字母小写。
4.3、使用命名空间注入
命名空间注入的方式是上面两种注入方式的简化操作,主要有p命名空间注入和c命名空间注入两种,p代表property(简化set注入方式),c代表constructor(简化构造器注入方式)
使用p命名空间注入 : xmlns:p=“http://www.springframework.org/schema/p”
- 引入命名空间
-
使用其替代set注入
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- 使用p命名空间进行注入,引入命名空间后,可以在bean标签属性中使用. p代表p命名空间, :后的为set方法后的名称, -ref代表应用其他bean的方式 --> <bean id="student" class="com.zero.pojo.Student" p:name="小强" p:address-ref="address"/> <!-- 创建Address类对象 --> <bean id="address" class="com.zero.pojo.Address"> <constructor-arg name="detail" value="广州"/> <constructor-arg name="mailCode" value="123456"/> </bean> </beans>
使用c命名空间注入: xmlns:c=“http://www.springframework.org/schema/c”
- 引入命名空间
-
使用其替代构造器注入
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:c="http://www.springframework.org/schema/c" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- 使用c命名空间进行注入,引入命名空间后,可以在bean标签属性中使用. c代表c命名空间, :后的为构造器的参数名称, -ref代表应用其他bean的方式 --> <bean id="user" class="com.zero.pojo.User" c:name="小强" c:gender="0" c:address-ref="address" /> <!-- 创建Address类对象 --> <bean id="address" class="com.zero.pojo.Address"> <constructor-arg name="detail" value="广州"/> <constructor-arg name="mailCode" value="123456"/> </bean> </beans>
5、spring的配置
5.1、bean
用于配置需要spring容器进行创建和托管的bean对象,使用方式参照上面的诸多例子。bean标签内提供了很多属性来设置该bean特性,主要有以下这些:
属性 | 作用 | 取值 | 默认值 |
---|---|---|---|
id | 唯一标识一个bean | 随意 | 无 |
name | 作为bean的别名,可存在多个(使用" ", ","等分隔) | 随意 | 无 |
autowire | 自动装配 | byName | byType | no | default | constructor | no |
scope | bean的生命周期范围(可指定单例、原型模式等等) | singleton | prototype | request | session | … | singeleton |
lazy-init | bean对象懒加载 | false | true | default | false |
5.2、alias
用于给创建的bean对象取别名。
使用方式
<!-- name用于绑定以配置的bean对象id, alias代表新取得别名 -->
<alias name="user" alias="u"/>
5.3、import
用于引入其他的bean.xml文件并合并为一个总的配置文件
使用方式
<!-- resources用于指定配置文件得路径 -->
<import resource="beans.xml"/>
6、自动装配
自动装配是指在依赖注入时,让spring容器自动去寻找已经存在的bean对象来装配现在配置的新bean对象。其使用的步骤如下:
- 构造环境
-
Cat类
package com.zero.pojo; /** * Cat类 */ public class Cat { public void shout(){ System.out.println("miaomiao~~~"); } }
-
Dog类
package com.zero.pojo; /** * Dog类 */ public class Dog { public void shout(){ System.out.println("wangwang~~~"); } }
-
Person类
package com.zero.pojo; /** * Person类 */ public class Person { //名字 private String name; //Dog对象 private Dog dog; //Cat对象 private Cat cat; public String getName() { return name; } public void setName(String name) { this.name = name; } public Dog getDog() { return dog; } public void setDog(Dog dog) { this.dog = dog; } public Cat getCat() { return cat; } public void setCat(Cat cat) { this.cat = cat; } }
- 在配置bean时,使用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">
<!-- 配置Cat对象 -->
<bean id="cat" class="com.zero.pojo.Cat"/>
<!-- 配置Dog对象 -->
<bean id="dog" class="com.zero.pojo.Dog"/>
<!--使用byName方式进行自动装配 -->
<bean id="person" class="com.zero.pojo.Person" autowire="byName"/>
<!-- 使用byType方式进行自动装配 -->
<!--<bean id="person" class="com.zero.pojo.Person" autowire="byType"/>-->
</beans>
注意
- byName方式要求容器中已经存在id和配置属性名字相同的bean,容器会根据属性的名字去找到对应id的bean.(准确的说不是属性的名字,而是setXxx()后的Xxx首字母小写的名称)
- byType方式要求容器中只存在同种类型的bean对象只有一个,否则会报错。
- 对于容器中没有的bean,会默认不装配
7、基于注解的spring配置
参考xml配置文件的方式,使用注解的方式来替代xml配置文件中所能做的一切事情。
7.1、使用@Configuration
注解替代xml配置文件
package com.zero.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
//@Configuration代表将该类注解为一个配置类
@Configuration
//@ComponentScan( value = {"com.zero.pojo"}) 代表扫描指定包下的注解,value是一个数组
@ComponentScan( value = {"com.zero.pojo"})
public class Config {
}
解释:
- @Configuration将类注解为一个配置类,相当于一个容器空壳。
- @ComponentScan( value = {“com.zero.pojo”}) 用于扫描value数组中的包,扫描包内的bean配置,将其放置到容器中。
7.2、使用@Component
注解替代xml配置文件中的< bean >标签
package com.zero.pojo;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
/**
* User类
*/
//@Component 代表将该类配置到spring容器中,有容器进行托管,相当于一个bean
@Component
public class User {
//名字
// @Value("zero")
private String name;
@Autowired
private Dog dog;
public String getName() {
return name;
}
@Value("zero")
public void setName(String name) {
this.name = name;
}
public Dog getDog() {
return dog;
}
public void setDog(Dog dog) {
this.dog = dog;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", dog=" + dog +
'}';
}
}
注意
-
@Component(value = “…”), value代表bean在容器中的id, 不写则为类名首字母小写。
-
该注解有以下几个衍生注解(意义一样,只是为了区别不同的使用场合)
- @Repository : 用于dao层的注解
- @Service:用于service层的注解
- @Controller:用于controller层的注解
- 也可以使用
@Bean
注解在配置类中定义方法来代替<bean>
标签
//value代表bean id, 缺省情况下为方法名
@Bean(value = "dog")
public Dog getDog(){
return new Dog();
}
7.3、使用@value
注解替代bean中的基本数据类型的注入
//名字
//@Value("zero") 代表为该基本数据类型属性注入一个值
@Value("zero")
private String name;
注意
- 该注解可以用于属性和set方法中
7.4、使用@Autowird
和@Requried
注解代替以注入bean对象
//使用@Autowired自动装配bean对象
@Autowired
private Dog dog;
注意
- @Autowired(required = false),其属性required代表该属性是否必须,true表示必须要,默认为true, false表示容器中不存在时可以为空
- @Autowired可以结合@@Qualifier(value = “…”) 来查找指定id的bean对象,value为bean id。
- 该注解可以用于属性和set方法中
7.5、使用新的方式加载注解类来代替加载xml配置文件
相比于配置文件使用ClassPathXmlApplicationContext类来加载配置文件,使用配置类的方式则使用AnnotationConfigApplicationContext类来加载配置属性,其他操作就没什么区别。如下:
@Test
public void test(){
//使用AnnotationConfigApplicationContext类来加载配置类
ApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
User user = context.getBean("user", User.class);
user.getDog().shout();
}
小细节
可以采用半配置文件半注解的方式来进行Spring的配置,不过需要引入context命名约束、开启注解支持、以及配置扫描含注解的包(扫描bean)
<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-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<!-- 开启注解支持 -->
<context:annotation-config/>
<!-- 扫描对应包内的注解 -->
<context:component-scan base-package="com.zero.pojo"/>
</beans>
7.6、其他一些注解
@Import
: 用于引入另一个类的bean配置@ComponentScan
: 扫描一个包内的bean配置@Bean
:用于主配置类中配置bean- @Scope: 用于标注bean对象的作用域
== 新手上路,恐有错漏,望客官看看即可,还得参照各路大神博文,以免被我误入歧途。==