开启注解扫描
applicationContext.xml中需要开启注解扫描
1 2 3 4 5 6 7 8 9 10 11 12 13
| <?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:component-scan base-package="com.example.bean.demo"/>
</beans>
|
使用注解定义Bean
- Spring2.5引入使用注解去定义Bean
- @Component 描述Spring框架中Bean
- 除了@Component外,Spring提供了3个功能基本和@Component等效的注解
- @Repository 用于对DAO实现类进行标注
- @Service 用于Service实现类进行标注
- @Controller 用于对Controller实现类进行标注
- 这三个注解是为了让标注类本身的用途清晰,Spring在后续版本会对其增强
编写类,并使用@Component注解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| package com.example.bean.demo;
import org.springframework.stereotype.Component;
@Component("userService") public class UserService { public String sayHello(String name) { return "Hello:" + name; } }
|
测试类,并执行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| package com.example.bean.demo;
import org.junit.jupiter.api.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;
class UserServiceTest {
@Test void sayHello() { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); UserService userService = (UserService) context.getBean("userService"); String s = userService.sayHello("张三"); System.out.println(s); } }
|
执行结果

Spring的属性注入-注解方式
- 使用@Autowired进行自动注入
- @Autowired默认按照类型进行注入
- @Autowired注入时可以针对成员变量或者set方法
- 通过@Autowired的required属性,设置一定要找到匹配的Bean
- 使用@Qualifier指定注入Bean的名称
- Spring提供对JSR-250中定义@Resource标准注解的支持
- 使用@Resource相当于@Autowired + @Qualifier
- @Resource和@Autowired注解功能相似
简单属性注入的注解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| package com.example.bean.demo;
import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service;
@Service("userService") public class UserService {
@Value("米饭") private String something;
public void eat() { System.out.println("eat:" + something); }
|
测试代码
1 2 3 4 5 6
| @Test void testEat() { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); UserService userService = (UserService) context.getBean("userService"); userService.eat(); }
|
执行结果

Spring的其他注解
Bean的生命周期
Spring初始化bean或销毁bean时,有时需要做一些处理工作,因此spring可以在创建和销毁bean的时候调用bean的两个生命周期的方法
1
| <bean id="xxx" calss="xxxx.xxxx.xxx" init-method="init" destroy-method="destroy"/>
|
- 当bean被载入到容器的时候调用init,注解方式:**@PostConstruct** 初始化
- 当bean从容器中删除的时候调用destroy(scope=singleton有效,多例时不知道需要销毁哪个则无效),注解方式:**@PreDestroy** 销毁
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| package com.example.bean.demo;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct; import javax.annotation.PreDestroy;
@Component("beanLifecycle") public class BeanLifecycle {
@PostConstruct public void init() { System.out.println("initBean..."); }
public void say() { System.out.println("hello..."); }
@PreDestroy public void destroy() { System.out.println("destroyBean..."); } }
|
测试代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| package com.example.bean.demo;
import org.junit.jupiter.api.Test; import org.springframework.context.support.ClassPathXmlApplicationContext;
class BeanLifecycleTest {
@Test void say() { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); BeanLifecycle beanLifecycle = (BeanLifecycle) context.getBean("beanLifecycle"); beanLifecycle.say(); context.close(); } }
|
执行结果

Bean的作用范围
- 使用注解配置的Bean和
<bean>
配置的一样,默认作用范围都是singleton
- @Scope注解用于指定Bean的作用范围
单例
默认是单例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| package com.example.bean.demo;
import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component;
@Component("beanScope") @Scope public class BeanScope { }
|
测试代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| package com.example.bean.demo;
import org.junit.jupiter.api.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;
class BeanScopeTest {
@Test void test() { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); BeanScope bean1 = (BeanScope) context.getBean("beanScope"); BeanScope bean2 = (BeanScope) context.getBean("beanScope"); System.out.println(bean1 == bean2); }
}
|
执行结果

多例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| package com.example.bean.demo;
import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component;
@Component("beanScope") @Scope("prototype") public class BeanScope { }
|
测试代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| package com.example.bean.demo;
import org.junit.jupiter.api.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;
class BeanScopeTest {
@Test void test() { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); BeanScope bean1 = (BeanScope) context.getBean("beanScope"); BeanScope bean2 = (BeanScope) context.getBean("beanScope"); System.out.println(bean1 == bean2); }
}
|
执行结果

传统XML配置和注解配置混合使用
- XML方式的优势
- 注解方式的优势
- XML与注解的整合开发
- 1、引入context命名空间
- 2、在配置文件中添加context:annotation-config标签
XML配置,set方式属性注入
此演示方式是用来进行对比
创建三个类,并进行引用
ProductService.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| package com.example.bean.demo.all;
public class ProductService {
private CategoryDao categoryDao;
private ProductDao productDao;
public void setCategoryDao(CategoryDao categoryDao) { this.categoryDao = categoryDao; }
public void setProductDao(ProductDao productDao) { this.productDao = productDao; }
public void save() { System.out.println("ProductService的save方法……"); categoryDao.save(); productDao.save(); } }
|
CategoryDao.java
1 2 3 4 5 6 7 8 9 10 11
| package com.example.bean.demo.all;
public class CategoryDao { public void save() { System.out.println("CategoryDao的save方法执行了……"); } }
|
ProductDao.java
1 2 3 4 5 6 7 8 9 10 11 12
| package com.example.bean.demo.all;
public class ProductDao {
public void save() { System.out.println("ProductDao的save方法执行了……"); } }
|
XML配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| <?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="productService" class="com.example.bean.demo.all.ProductService"> <property name="productDao" ref="productDao"/> <property name="categoryDao" ref="categoryDao"/> </bean>
<bean id="productDao" class="com.example.bean.demo.all.ProductDao"/>
<bean id="categoryDao" class="com.example.bean.demo.all.CategoryDao"/>
</beans>
|
测试代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| package com.example.bean.demo.all;
import org.junit.jupiter.api.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;
class ProductServiceTest {
@Test void test1() { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext-all.xml"); ProductService productService = (ProductService) context.getBean("productService"); productService.save(); }
}
|
执行结果

XML配置与注解混合使用
XML只管理类,注解的方式进行属性注入
改造ProductService.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| package com.example.bean.demo.all;
import javax.annotation.Resource;
public class ProductService {
@Resource(name = "categoryDao") private CategoryDao categoryDao;
@Resource(name = "productDao") private ProductDao productDao;
public void save() { System.out.println("ProductService的save方法……"); categoryDao.save(); productDao.save(); } }
|
XML文件改造
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| <?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:annotation-config/> <bean id="productService" class="com.example.bean.demo.all.ProductService"/>
<bean id="productDao" class="com.example.bean.demo.all.ProductDao"/>
<bean id="categoryDao" class="com.example.bean.demo.all.CategoryDao"/>
</beans>
|
其他均不变,执行结果是一致的