一、IOC的概念与原理
IOC(控制反转),把对象创建和对象之间的调用过程,交给Spring进行管理。使用IOC,可以将程序的耦合度降低。
IOC的底层主要使用了xml解析、工厂模式、反射这三个部分。IOC思想基于IOC容器完成,IOC容器底层就是对象工厂。Spring提供了IOC容器实现的两种方式(两个接口):(1)beanfactory,IOC容器基本实现方式,是Spring内部使用的接口,加载配置文件时,不会创建对象,在获取(使用)对象时,才会创建对象;(2)ApplicationContext,是beanfactory接口的子接口,提供了更多更强大的功能,加载配置文件时,就会把在配置文件对象进行创建;
IOC底层原理:
第一步 配置xml文件,配置创建的对象
<bean id="dao" class="star.light.UserDao"></bean>
第二步 创建Serivice类和DAO类,创建工厂类
clss UserFactory{
public static UserDao getDao(){
String classValue = class属性值; // 1.通过xml解析
Class clazz = Class.forname(classValue); // 2.通过反射创建对象
return (UserDao)clazz.newInstance();
}
}
二、IOC操作Bean管理
Bean管理指的是两个操作:(1)Spring创建对象;(2)Spring注入属性;Bean管理操作有两种方式,一种是基于xml配置文件方式实现,另一种是基于注解方式实现。
2.1、基于xml配置文件方式实现Bean管理
2.1.1、基于xml配置文件方式创建对象和属性注入
- 基于xml方式创建对象
- 基于xml方式注入属性
package star.light.test;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClasspathXmlApplicationContext;
import star.light.spring.User;
public class TestSpring {
@Test
public void testSpring(){
ApplicationContext context = new ClasspathXmlApplicationContext("spring.xml");
User user = context.getBean("user", User.class);
System.out.println(user);
}
}
package star.light.bean;
public class User {
private String id;
private String name;
private int age;
public User() {
}
public User(String name, int age) {
this.name = name;
this.age = age;
}
public User(String id, String name, int age) {
this.id = id;
this.name = name;
this.age = age;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
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;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
'}';
}
}
其中,spring.xml配置文件存放在【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">
<!--配置User对象的创建-->
<bean id="user" class="star.light.bean.User">
<!--使用setXxxx()进行属性注入
使用property完成属性注入
name:类里面属性名称
value:向属性注入的值
-->
<property name="id" value="1"></property>
<!--使用有参构造器注入属性
使用constructor-arg完成属性注入
name:类里面属性名称
value:向属性注入的值
index:有参构造器中属性的索引值
-->
<constructor-arg name="name" value="Sakura"></constructor-arg>
<constructor-arg index="1" value="9"></constructor-arg>
</bean>
</beans>
使用p名称注入空间,可以简化基于xml的配置方式
第一步:添加p名称空间在配置文件中
第二步:进行属性注入,在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"
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">
<bean id="user" class="star.light.bean.User" p:id="2" p:name="Mikoto" p:age="13"></bean>
</beans>属性值为null值或者包含特殊符号
属性值为null值或者包含特殊符号
<?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="user" class="star.light.bean.User">
<!--属性值为null-->
<property name="name"><null/></property>
<!--属性值包含特殊符号
第一种方式:使用转义字符
第二种方式:把带特殊符号的内容写到CDATA中<![CDATA[带特殊符号的值]]>
-->
<property name="id">
<value><![CDATA[@001<[x]>]]></value>
</property>
</bean>
</beans>
2.1.2、xml注入其它类型属性
package star.light.test;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClasspathXmlApplicationContext;
import star.light.service.UserService;
public class TestSpring {
@Test
public void testBean(){
ApplicationContext context = new ClasspathXmlApplicationContext("spring.xml");
UserService userService = context.getBean("userService", UserService.class);
userService.append();
}
}
package star.light.service;
import star.light.dao.UserDao;
public class UserService {
//创建 UserDao 类型属性,生成 set 方法
private UserDao userDao;
public void append(){
System.out.println("service append...");
userDao.update();
}
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
}
package star.light.dao;
public interface UserDao {
public void update();
public int add(int a,int b);
}
package star.light.dao;
public class UserDaoImpl implements UserDao {
@Override
public int add(int a, int b) {
System.out.println("add()执行");
return a+b;
}
@Override
public void update() {
System.out.println("dao update...");
}
}
其中,spring.xml配置文件存放在【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">
<!--servlet对象创建-->
<bean id="userService" class="star.light.service.UserService">
<!--注入userDAO对象
name属性值:类里面属性名称
ref属性:创建userDaodao对象bean标签ID值
-->
<property name="userDao" ref="userDaoImpl"></property>
</bean>
<!--dao对象创建-->
<bean id="userDaoImpl" class="star.light.dao.UserDaoImpl"></bean>
</beans>
- 注入属性-内部 bean
package star.light.test;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClasspathXmlApplicationContext;
import star.light.bean.Employee;
public class TestSpring {
@Test
public void testBean(){
ApplicationContext context = new ClasspathXmlApplicationContext("spring.xml");
Employee employee = context.getBean("employee", Employee.class);
System.out.println(employee);
}
}
package star.light.bean;
public class Employee {
private String employeeId;
private String name;
private String genger;
private int age;
private Department department;
public Employee() {
}
public Employee(String employeeId, String name, String genger, int age) {
this.employeeId = employeeId;
this.name = name;
this.genger = genger;
this.age = age;
}
public String getEmployeeId() {
return employeeId;
}
public void setEmployeeId(String employeeId) {
this.employeeId = employeeId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getGenger() {
return genger;
}
public void setGenger(String genger) {
this.genger = genger;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Department getDepartment() {
return department;
}
public void setDepartment(Department department) {
this.department = department;
}
@Override
public String toString() {
return "Employee{" +
"employeeId='" + employeeId + '\'' +
", name='" + name + '\'' +
", genger='" + genger + '\'' +
", age='" + age + '\'' +
", department=" + department +
'}';
}
}
package star.light.bean;
public class Department {
private String departmentId;
private String departmentName;
public Department() {
}
public Department(String departmentId, String departmentName) {
this.departmentId = departmentId;
this.departmentName = departmentName;
}
public String getDepartmentId() {
return departmentId;
}
public void setDepartmentId(String departmentId) {
this.departmentId = departmentId;
}
public String getDepartmentName() {
return departmentName;
}
public void setDepartmentName(String departmentName) {
this.departmentName = departmentName;
}
@Override
public String toString() {
return "Department{" +
"departmentId='" + departmentId + '\'' +
", departmentName='" + departmentName + '\'' +
'}';
}
}
其中,spring.xml配置文件存放在【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-->
<bean id="employee" class="star.light.bean.Employee">
<!--设置属性-->
<property name="name" value="sakura"></property>
<property name="genger" value="女"></property>
<!--设置对象类型属性-->
<property name="department">
<bean id="dempartment" class="star.light.bean.Department">
<property name="departmentName" value="开发部"></property>
</bean>
</property>
</bean>
</beans>
<?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="employee" class="star.light.bean.Employee">
<!--设置属性-->
<property name="name" value="sakura"></property>
<property name="genger" value="女"></property>
<!--第一种方式级联赋值-->
<property name="department" ref="dempartment"></property>
<!--第二种方式级联赋值,需要生成对应的getXxxx()-->
<property name="department.departmentId" value="001"></property>
</bean>
<bean id="dempartment" class="star.light.bean.Department">
<property name="departmentName" value="开发部"></property>
</bean>
</beans>
Employee.java、Department.java、TestSpring.java内容同上;
2.1.3、xml注入集合属性
package star.light.test;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClasspathXmlApplicationContext;
import star.light.collection.CollectionTest;
public class TestSpring {
@Test
public void testBean(){
ApplicationContext context = new ClasspathXmlApplicationContext("spring.xml");
CollectionTest collection = context.getBean("collection", CollectionTest.class);
System.out.println(collection);
}
}
package star.light.collection;
import star.light.bean.User;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class CollectionTest {
private String[] array; //数组类型属性
private List<String> list; //list集合类型属性
private Map<String,String> map; //map类型属性
private Set<String> set; //set集合类型属性
private List<User> users; //list集合类型属性,值是对象
public void setArray(String[] array) {
this.array = array;
}
public void setList(List<String> list) {
this.list = list;
}
public void setMap(Map<String, String> map) {
this.map = map;
}
public void setSet(Set<String> set) {
this.set = set;
}
public void setUsers(List<User> users) {
this.users = users;
}
@Override
public String toString() {
return "CollectionTest{" +
"array=" + Arrays.toString(array) +
", list=" + list +
", map=" + map +
", set=" + set +
", users=" + users +
'}';
}
}
其中,spring.xml配置文件存放在【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="collection" class="star.light.collection.CollectionTest">
<!--数组类型的注入-->
<property name="array">
<array>
<value>Sakura</value>
<value>Mikoto</value>
</array>
</property>
<!--list集合类型注入-->
<property name="list">
<list>
<value>Java</value>
<value>Python</value>
</list>
</property>
<!--map类型属性注入-->
<property name="map">
<map>
<entry key="1" value="one"></entry>
<entry key="2" value="two"></entry>
</map>
</property>
<!--set集合属性注入-->
<property name="set">
<set>
<value>Unreal Engine</value>
<value>Unity3D</value>
</set>
</property>
<!--注入list集合属性,值是对象-->
<property name="users">
<list>
<ref bean="user01"></ref>
<ref bean="user02"></ref>
</list>
</property>
</bean>
<!--创建多个user对象-->
<bean id="user01" class="star.light.bean.User">
<property name="id" value="001"></property>
<property name="name" value="Sakura"></property>
<property name="age" value="9"></property>
</bean>
<bean id="user02" class="star.light.bean.User">
<property name="id" value="002"></property>
<property name="name" value="Mikoto"></property>
<property name="age" value="13"></property>
</bean>
</beans>
其中,User.java内容同上;
2.1.4、提取集合注入部分
其中,spring.xml配置文件存放在【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"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
<!-- 1.提取list集合类型属性注入-->
<util:list id="course">
<value>Java</value>
<value>Python</value>
<value>Unreal Engine</value>
<value>STM32</value>
</util:list>
<!-- 2.提取list集合类型属性注入使用-->
<bean id="collection" class="star.light.collection.CollectionTest">
<property name="list" ref="course"></property>
</bean>
</beans>
其中,CollectionTest.java、TestSpring.java内容同上;
三、factorybean
Spring 有两种类型 bean,一种普通 bean,另外一种工厂 bean(factorybean)。普通 bean:在配置文件中定义 bean 类型就是返回类型;工厂 bean:在配置文件定义 bean 类型可以和返回类型不一样;
那如何自定义factorybean呢?
- 第一步 创建类,让这个类作为工厂bean,实现接口factorybean
- 第二步 实现接口里面的方法,在实现的方法中定义返回bean类型
package star.light.test;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClasspathXmlApplicationContext;
import star.light.bean.User;
public class TestSpring {
@Test
public void testBean(){
ApplicationContext context = new ClasspathXmlApplicationContext("spring.xml");
User user = context.getBean("factorybean", User.class);
System.out.println(user);
}
}
package star.light.factorybean;
import org.springframework.beans.factory.factorybean;
import star.light.bean.User;
public class Myfactorybean implements factorybean<User> {
//定义返回bean
@Override
public User getobject() throws Exception {
User user = new User();
user.setName("Sakura");
user.setAge(9);
return user;
}
@Override
public Class<?> getobjectType() {
return null;
}
@Override
public boolean isSingleton() {
return false;
}
}
其中,spring.xml配置文件存放在【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="factorybean" class="star.light.factorybean.Myfactorybean"></bean>
</beans>
其中,User.java内容同上;
四、Bean的作用域与生命周期
4.1、Bean的作用域
在 Spring 里面,bean 作用域可以设置创建 bean 实例是单实例还是多实例。在 Spring 里面,默认情况下,bean 是单实例对象。在 spring 配置文件 bean 标签里面有属性(scope)用于设置单实例还是多实例,scope=singleton(默认值),表示是单实例对象;scope=prototype,表示是多实例对象。
singleton 和 prototype 区别?
- singleton 表示单实例,prototype 表示多实例
- 设置 scope 值是 singleton 时候,加载 spring 配置文件时候就会创建单实例对象;
- 设置 scope 值是 prototype 时候,不是在加载 spring 配置文件时候创建 对象,在调用getBean 方法时候创建多实例对象;
package star.light.test;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClasspathXmlApplicationContext;
import star.light.bean.Employee;
import star.light.bean.User;
public class TestSpring {
@Test
public void testBean(){
ApplicationContext context = new ClasspathXmlApplicationContext("spring.xml");
User user01 = context.getBean("user", User.class);
User user02 = context.getBean("user", User.class);
System.out.println("user01==user02:" + (user01==user02));
Employee employee01 = context.getBean("employee",Employee.class);
Employee employee02 = context.getBean("employee",Employee.class);
System.out.println("employee01==employee02:" + (employee01==employee02));
}
}
其中,spring.xml配置文件存放在【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="user" class="star.light.bean.User"></bean>
<bean id="employee" class="star.light.bean.Employee" scope="prototype"></bean>
</beans>
其中,User.java、Employee.java内容同上;
4.2、Bean的生命周期
- 通过构造器创建 bean 实例(无参数构造)
- 为 bean 的属性设置值和对其他 bean 引用(调用 set 方法)
- 把 bean 实例传递 bean 后置处理器的方法 postProcessBeforeInitialization()
- 调用 bean 的初始化的方法(需要进行配置初始化的方法)
- 把 bean 实例传递 bean 后置处理器的方法 postProcessAfterInitialization()
- bean 可以使用了(对象获取到了)
- 当容器关闭时候,调用 bean 的销毁的方法(需要进行配置销毁的方法)
package star.light.test;
import org.junit.Test;
import org.springframework.context.support.ClasspathXmlApplicationContext;
import star.light.bean.Person;
public class TestSpring {
@Test
public void testBean(){
ClasspathXmlApplicationContext context = new ClasspathXmlApplicationContext("spring.xml");
Person person = context.getBean("person", Person.class);
System.out.println("获取创建bean实例的对象");
System.out.println(person);
context.close(); //手动让bean实例销毁
}
}
package star.light.lifecycle;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("调用postProcessBeforeInitialization()");
return null;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("调用postProcessAfterInitialization()");
return null;
}
}
package star.light.bean;
public class Person {
private String name;
private int age;
public Person() {
System.out.println("执行了无参构造器");
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
//创建执行的初始化方法
public void init(){
System.out.println("调用初始化方法");
}
//创建对象的销毁方法
public void destory(){
System.out.println("调用销毁方法");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
System.out.println("调用setXxxx()设置name属性");
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
System.out.println("调用setXxx()设置age属性");
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
其中,spring.xml配置文件存放在【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">
<!--init-method 配置初始化方法;destroy-method 配置销毁方法-->
<bean id="person" class="star.light.bean.Person" init-method="init" destroy-method="destory">
<property name="name" value="Sakura"></property>
<property name="age" value="9"></property>
</bean>
<!--配置后置处理器-->
<bean id="myBeanPost" class="star.light.lifecycle.MyBeanPostProcessor"></bean>
</beans>
五、XML自动装配
自动装配是指根据指定装配规则(属性名称或者属性类型),Spring 自动将匹配的属性值进行注入。
package star.light.test;
import org.junit.Test;
import org.springframework.context.support.ClasspathXmlApplicationContext;
import star.light.bean.Employee;
public class TestSpring {
@Test
public void testBean(){
ClasspathXmlApplicationContext context = new ClasspathXmlApplicationContext("spring.xml");
Employee employee = context.getBean("employee",Employee.class);
System.out.println(employee);
}
}
其中,spring.xml配置文件存放在【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标签属性autowire,配置自动装配
autowire属性常用的值
byName 根据属性名称注入,注入bean的id值和属性名称一样
byType 根据属性类型注入,使用属性类型注入时,相同类型的bean不能定义多个,否则报错
-->
<bean id="employee" class="star.light.bean.Employee" autowire="byName"></bean>
<bean id="department" class="star.light.bean.Department"></bean>
</beans>
其中,Employee.java、Department.java内容同上;
六、外部属性文件
- 创建外部属性文件,properties 格式文件,写数据库信息
- 把外部 properties 属性文件引入到 spring 配置文件中
- 引入 context 名称空间
- 在 spring 配置文件使用标签引入外部属性文件
要使用数据库连接池技术,需要先将相应的jar包导入工程中。这里,我是用的阿里巴巴开发的德鲁伊的jar包(druid-1.1.9.jar
)。
其中,spring.xml配置文件存放在【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"
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.xsd">
<!--引入外部的属性文件-->
<context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
<!--配置连接池-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${prop.driverClass}"></property>
<property name="url" value="${prop.url}"></property>
<property name="username" value="${prop.username}"></property>
<property name="password" value="${prop.password}"></property>
</bean>
</beans>
其中,jdbc.properties配置文件存放在【src】目录下,内容如下:
# MysqL8.0之前的版本写 com.MysqL.jdbc.Driver
# MysqL8.0之后的版本写 com.MysqL.cj.jdbc.Driver
prop.driverClass=com.MysqL.cj.jdbc.Driver
prop.url=jdbc:MysqL://localhost:3306/test
prop.userName=root
prop.password=123abc
七、基于注解方式实现Bean管理
7.1、什么是注解
注解是代码特殊标记,格式:@注解名称(属性名称=属性值, 属性名称=属性值..)。注解作用在类上面,方法上面,属性上面。我们可以使用注解目的来简化 xml 配置。
Spring 针对 Bean 管理中创建对象提供了以下注解:
- @Component
- @Service(建议用在Seivice层)
- @Controller(建议用在web层)
- @Repository(建议用在DAO层);
以上四个注解功能是一样的,都可以用来创建 bean 实例。
Spring 针对 Bean 管理中注入属性提供了以下注解:
- @AutoWired(根据属性类型进行自动装配)
- @Qualifier(根据属性名称进行注入,与@AutoWired一起使用)
- @Resource(可以根据类型注入,也可以根据名称注入,该注解在jdk中的扩展包javax中声明的,在jdk 11以上的版本移除了)
- @Value(注入普通类型属性)
7.2、基于注解方式创建对象和属性注入
package star.light.test;
import org.junit.Test;
import org.springframework.context.support.ClasspathXmlApplicationContext;
import star.light.service.UserService;
public class TestSpring {
@Test
public void testSeriver(){
ClasspathXmlApplicationContext context = new ClasspathXmlApplicationContext("spring.xml");
UserService userService = context.getBean("userService", UserService.class);
userService.append();
}
}
package star.light.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import star.light.dao.UserDao;
//在注解里面value属性值可以省略不屑,默认值是类的名称,首字母小写
@Service(value = "userService")
public class UserService {
//创建 UserDao 类型属性,不需要生成 set 方法,添加注入属性注解
@Autowired //根据类型进行注入
@Qualifier(value = "userDaoImpl") //根据名称进行注入
private UserDao userDao;
@Value(value = "sakura")
private String name;
public void append(){
System.out.println("service append...");
System.out.println(name);
userDao.update();
}
}
package star.light.dao;
import org.springframework.stereotype.Repository;
@Repository
public class UserDaoImpl implements UserDao {
@Override
public int add(int a, int b) {
System.out.println("add()执行");
return a+b;
}
@Override
public void update() {
System.out.println("dao update...");
}
}
其中,spring.xml配置文件存放在【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"
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.xsd">
<!--开启组件扫描
1 如果要扫描多个包,多个包使用逗号隔开
2 如果要扫描多个包,可以写扫描包上层目录108
-->
<context:component-scan base-package="star.light"></context:component-scan>
<!--
use-default-filters="false" 表示现在不使用默认 filter,自己配置 filter
context:include-filter ,设置扫描哪些内容
-->
<!--
<context:component-scan base-package="star.light" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Component"></context:include-filter>
</context:component-scan>
-->
<!--
下面配置扫描所有内容
context:exclude-filter,设置哪些内容不进行扫描
-->
<!--
<context:component-scan base-package="star.light">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"></context:exclude-filter>
</context:component-scan>
-->
</beans>
其中,UserDao.java内容同上;
7.3、完全注解开发
- 创建配置类,替代 xml 配置文件
- 编写测试类
package star.light.test;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import star.light.config.SpringConfig;
import star.light.service.UserService;
public class TestSpring {
@Test
public void testSeriver(){
//加载配置类
ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
UserService userService = context.getBean("userService",UserService.class);
userService.add();
}
}
package star.light.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration //作为配置类,替代xml配置文件
@ComponentScan(basePackages = {"star.light"}) //开启组件扫描
public class SpringConfig {
}
其中,UserDao.java、UserDaoImpl.java、UserService.java内容同上;