spring–基础–05–基于注解的配置
代码地址
https://gitee.com/DanShenGuiZu/learnDemo.git
1、介绍
- @Required:应用于bean属性的setter方法。
- @Autowired:应用到bean属性的setter方法,非setter方法,构造函数和属性。
- @Qualifier:指定确切的的bean, @Autowired和@Qualifier注解可以用来删除混乱。
- JSR-250Annotations:支持JSR-250的基础的注解
- @Resource
- @PostConstruct
- @PreDestroy
<?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-3.0.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!--开启注解配置-->
<context:annotation-config/>
</beans>
2、@Required(不建议使用)
应用于bean属性的setter方法,它表明受影响的bean属性在配置时必须放在XML配置文件中,否则容器就会抛出一个BeanInitializationException异常。
3、@Autowired
- 应用到bean属性的setter方法,非setter方法,构造函数和属性。
- 将容器中的bean注入到当前对象中
3.1、应用于构造函数
3.2、应用于setter方法
3.3、应用于具有任意名称和多个参数的方法
<?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-3.0.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!--开启注解配置-->
<context:annotation-config/>
<bean id="HelloWorld1" class=" com.example.demolearn.other.spring.demo2.HelloWorld1">
</bean>
<bean id="HelloWorld2" class=" com.example.demolearn.other.spring.demo2.HelloWorld2">
</bean>
<bean id="HelloWorld3" class=" com.example.demolearn.other.spring.demo2.HelloWorld3">
</bean>
</beans>
public class HelloWorld1 {
}
public class HelloWorld3 {
}
public class HelloWorld2 {
private HelloWorld1 helloWorld1;
private HelloWorld3 helloWorld3;
@Autowired
public void PPHelloWorld1(HelloWorld1 helloWorld1,HelloWorld3 helloWorld3){
this.helloWorld1 = helloWorld1;
this.helloWorld3 = helloWorld3;
}
public void sayHelloWorld1(){
System.out.println(helloWorld1.toString());
System.out.println(helloWorld3.toString());
}
public static void main(String[] args){
String pathHello = "./other\\Bean2.xml";
AbstractApplicationContext context = new ClassPathXmlApplicationContext(pathHello);
HelloWorld2 HelloWorld2 =(HelloWorld2)context.getBean("HelloWorld2");
HelloWorld2.sayHelloWorld1();
}
}
输出:
com.example.demolearn.other.spring.demo2.HelloWorld1@157632c9
com.example.demolearn.other.spring.demo2.HelloWorld3@6ee12bac
3.4、应用于字段(推荐)
<?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-3.0.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!--开启注解配置-->
<context:annotation-config/>
<bean id="HelloWorld1" class=" com.example.demolearn.other.spring.demo2.HelloWorld1">
</bean>
<bean id="HelloWorld2" class=" com.example.demolearn.other.spring.demo2.HelloWorld2">
</bean>
</beans>
public class HelloWorld2 {
@Autowired
private HelloWorld1 helloWorld1;
public void sayHelloWorld1(){
System.out.println(helloWorld1.toString());
}
public static void main(String[] args){
String pathHello = "./other\\Bean2.xml";
AbstractApplicationContext context = new ClassPathXmlApplicationContext(pathHello);
HelloWorld2 HelloWorld2 =(HelloWorld2)context.getBean("HelloWorld2");
HelloWorld2.sayHelloWorld1();
}
}
public class HelloWorld2 {
@Autowired
private HelloWorld1 helloWorld1;
public void sayHelloWorld1(){
System.out.println(helloWorld1.toString());
}
public static void main(String[] args){
String pathHello = "./other\\Bean2.xml";
AbstractApplicationContext context = new ClassPathXmlApplicationContext(pathHello);
HelloWorld2 HelloWorld2 =(HelloWorld2)context.getBean("HelloWorld2");
HelloWorld2.sayHelloWorld1();
}
}
输出:
com.example.demolearn.other.spring.demo2.HelloWorld1@731f8236
3.5、应用于容器(List,Set,Map)
4、@Qualifier
- 当你创建多个具有相同类型的bean时,并且想要用一个属性只为它们其中的一个进行装配,在这种情况下,你可以使用@Qualifier和@Autowired来指定确切的bean。
5、SpringJSR-250注解
- @PostConstruct:对象初始化后被调用,是对init-method的替代。
- @PreDestroy:bean从容器中删除之前被调用,是对destroy-method的替代。
- @Resource:
- 应用于字段中或者setter方法中
- 使用一个’name’属性,该属性以一个bean名称的形式被注入。它遵循by-name自动连接语义.
- 如果没有明确地指定一个’name’,默认名称源于字段名或者setter方法。
- 在字段的情况下,它使用的是字段名;
- 在一个setter方法情况下,它使用的是bean属性名称。
输出:
HelloWorld5_1:对象初始化后动作
com.example.demolearn.other.spring.demo2.HelloWorld5@6b419da
..... - Closing org.springframework.context.support.ClassPathXmlApplicationContext@7a46a697, started on Sun Sep 20 07:10:35 CST 2020
HelloWorld5_1:销毁对象前动作
6、基于Java的配置
- @Configuration:将当前类定义的bean放到SpringIoC容器中。
- @Bean: 方法中定义一个bean
- 该bean会放到SpringIoC容器中
- 方法名称作为bean的ID
- 它创建并返回实际的bean。
- @import:允许从另一个配置类中加载@Bean定义。
6.1、简单案例01
输出:
com.example.demolearn.other.spring.demo2.HelloWorld6@1372ed45
6.2、注入Bean的依赖性 案例02
- 当@Beans依赖对方时,表达这种依赖性非常简单,只要有一个bean方法调用另一个,如下所示:
輸出:
com.example.demolearn.other.spring.demo2.HelloWorld8@7364985f
com.example.demolearn.other.spring.demo2.HelloWorld7@5d20e46
6.3、@Import
允许从另一个配置类中加载@Bean定义。
输出:
com.example.demolearn.other.spring.demo2.HelloWorld8@61d47554
com.example.demolearn.other.spring.demo2.HelloWorld7@69b794e2
6.4、生命周期回调
输出:
HelloWorld10:对象初始化后动作
com.example.demolearn.other.spring.demo2.HelloWorld10@37574691
..... - Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@67f89fa3, started on Sun Sep 20 07:57:01 CST 2020
HelloWorld10:销毁对象前动作
7、Spring中的事件处理
- 通过ApplicationEvent类和ApplicationListener接口支持。
- 如果一个bean实现ApplicationListener,那么每次ApplicationEvent被发布到ApplicationContext上,那个bean会被通知。
- Spring的事件处理是单线程的,如果一个事件被发布,只要有一个接收者得到的该消息,该进程被阻塞并且流程将不会继续。因此,如果事件处理被使用,在设计应用程序时应注意。
7.1、Spring内置事件
- ContextRefreshedEvent:
- ApplicationContext被初始化或刷新时,该事件触发。
- 也可以在ConfigurableApplicationContext接口中使用refresh()方法来发生。
- ContextStartedEvent:
- 当使用ConfigurableApplicationContext接口中的start()方法启动ApplicationContext时,该事件触发。
- 可以在接受到这个事件后重启任何停止的应用程序。
- ContextStoppedEvent
- 当使用ConfigurableApplicationContext接口中的stop()方法停止ApplicationContext时,该事件触发。
- 可以在接受到这个事件后做必要的清理的工作。
- ContextClosedEvent
- 当使用ConfigurableApplicationContext接口中的close()方法关闭ApplicationContext时,该事件触发。
- 一个已关闭的上下文到达生命周期末端;它不能被刷新或重启。
5.RequestHandledEvent - 是一个web-specific事件
- 告诉所有bean HTTP请求已经被服务。
7.2、案例
输出:
上下文启动事件
com.example.demolearn.other.spring.demo3.HelloEvent1@7fe8ea47
上下文停止事件
7.3、Spring中的自定义事件(参考代码)
public class HelloEvent2 extends ApplicationEvent {
public HelloEvent2(Object source){
super(source);
}
public void showMessage(){
System.out.println("HelloEvent2--->showMessage ");
}
}
public class HelloEvent2_L1 implements ApplicationListener<HelloEvent2> {
@Override
public void onApplicationEvent(HelloEvent2 event){
event.showMessage();
}
}
public class HelloEvent2Publisher implements ApplicationEventPublisherAware {
private ApplicationEventPublisher publisher;
@Override
public void setApplicationEventPublisher(ApplicationEventPublisher publisher){
this.publisher = publisher;
}
public void publish(){
HelloEvent2 ce = new HelloEvent2(this);
publisher.publishEvent(ce);
}
}
@Configurable // 相当于Bean2.xml
public class HelloEvent2_C {
@Bean
public HelloEvent2_L1 HelloEvent2_L1(){
return new HelloEvent2_L1();
}
@Bean
public HelloEvent2Publisher HelloEvent2Publisher(){
return new HelloEvent2Publisher();
}
public static void main(String[] args){
// 当实例化上下文时,不需要同时指定HelloWorld8_1.class和HelloWorld6_1.class,只有HelloWorld9类需要提供
ConfigurableApplicationContext context = new AnnotationConfigApplicationContext(HelloEvent2_C.class);
HelloEvent2Publisher cvp =
(HelloEvent2Publisher)context.getBean("HelloEvent2Publisher");
cvp.publish();
}
}
输出:
HelloEvent2--->showMessage