一:ApplicationContextAware接口

实现ApplicationContextAware接口,重写setApplicationContext方法,可以将spring容器上下文对象注入,

然后持有spring上下文对象,可以通过该对象获取spring容器中注册的任何bean实例。

/**
* @author Administrator
* 实现ApplicationContextAware接口,重写setApplicationContext方法,会注入
* spring上下文对象,可以在程序中持有一个context的对象,通过context,我们可以获取任何
* spring容器管理的bean
*/
public class ApplicationContextUtils implements ApplicationContextAware{ private static ApplicationContext context; @Override
public void setApplicationContext(ApplicationContext context) throws BeansException {
ApplicationContextUtils.context = context;
} public static ApplicationContext getApplicationContext(){
return context;
} /**
* 通过beanName获取实例bean
* @param beanName
* @return
*/
@SuppressWarnings("unchecked")
public static <T> T getBean(String beanName){
return (T) context.getBean(beanName);
} /**
* 通过类型获取实例bean,但是如果在spring容器中通过相同的类
* 的不同构造器创建两个不同的对象,通过类型则获取不到对象
* @param clazz
* @return
*/
@SuppressWarnings("unchecked")
public static <T> T getBean(Class<?> clazz){
return (T) context.getBean(clazz);
} }

  

测试两种获取实例bean的方式:

@Test
public void testAppContext() {
String conf = "applicationContext.xml";
ApplicationContext context = new ClassPathXmlApplicationContext(conf);
Emp emp = ApplicationContextUtils.getBean("emp");
System.out.println(emp);
Emp emp2 = ApplicationContextUtils.getBean(Emp.class);
System.out.println(emp2);
}

  

Emp [name=null, age=null, salary=null]
Emp [name=null, age=null, salary=null]

 可以获取对象,但是如果xml中注册两个相同类型的bean,就会出问题:

<!-- 实例化对象,默认调用无参数构造器 -->
<bean id="emp" class="com.hlcui.entity.Emp" init-method="init"></bean> <!-- 实例化对象,有参数构造器 -->
<bean id="emp2" class="com.hlcui.entity.Emp">
<property name="name" value="Tom"></property>
<property name="age" value="12"></property>
<property name="salary" value="14000.0"></property>
</bean>

 

实现ApplicationContextAware接口的同时,还要将类 ApplicationContextUtils 交给spring容器管理,这样在

spring容器启动的时候才会将该对象注册,当检测到该类实现该接口时,会把spring上下文对象注入。

下面看一下接口源码:

public interface ApplicationContextAware
extends Aware
{ public abstract void setApplicationContext(ApplicationContext applicationcontext)
throws BeansException;
}

 ApplicationContextAware接口内部只有一个抽象方法setApplicationContext(),同时又继承Aware接口

Aware接口:

public interface Aware
{
}

 空接口,就是一个标记

二:InitializingBean接口

实现该接口的类,需要重写 afterPropertiesSet() ,在实例化的时候,调用完构造方法创建对象之后,会调用

该方法执行一个初始化bean的动作,作用类似@PostContrcut注解和xml中配置的init-method属性,但是执行顺序

有区别

/**
* @author Administrator
* 员工Emp类,实现InitializingBean接口,重写afterPropertiesSet方法,还有注解@PostConstruct,同时还有
* 在实例化Emp的时候,配置了init-method="init"属性
*/
public class Emp implements InitializingBean{ private String name; private Integer age; private Double salary; public Emp(){
System.out.println("constructor...");
} @Override
public void afterPropertiesSet() throws Exception {
System.out.println("InitializingBean...afterPropertiesSet");
} @PostConstruct
public void reload(){
System.out.println("@PostConstruct");
} public void init(){
System.out.println("method-init");
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public Integer getAge() {
return age;
} public void setAge(Integer age) {
this.age = age;
} public Double getSalary() {
return salary;
} public void setSalary(Double salary) {
this.salary = salary;
} @Override
public String toString() {
return "Emp [name=" + name + ", age=" + age + ", salary=" + salary + "]";
} }

  

spring容器xml中配置:

<!-- 该配置扫描注解到spring容器 -->
<context:annotation-config/> <bean id="applicationContextUtils" class="com.hlcui.util.ApplicationContextUtils"></bean> <!-- 实例化对象,默认调用无参数构造器 -->
<bean id="emp" class="com.hlcui.entity.Emp" init-method="init"></bean> <!-- 实例化对象,有参数构造器 -->
<bean id="emp2" class="com.hlcui.entity.Emp">
<property name="name" value="Tom"></property>
<property name="age" value="12"></property>
<property name="salary" value="14000.0"></property>
</bean>

  

 <context:annotation-config/> 的作用是扫描注解到spring容器,但是它的作用有限制,不能用作扫描service,controller,component等
组件注册到spring,例如:<context:component-scan = "com.hlcui.*"/> 它的作用是扫描组件,包括上面的配置。

执行结果如下:

constructor...
@PostConstruct
InitializingBean...afterPropertiesSet
method-init
constructor...
@PostConstruct
InitializingBean...afterPropertiesSet

  首先执行第一条:

<bean id="emp" class="com.hlcui.entity.Emp" init-method="init"></bean>
1:执行构造器,创建对象
2:创建对象之后,调用有@PostContruct注解的方法初始化bean对象
3:调用afterProptertiesSeet方法初始化对象
4:调用xml中配置的init-method方法初始化对象
执行第2条语句:
<bean id="emp2" class="com.hlcui.entity.Emp">
<property name="name" value="Tom"></property>
<property name="age" value="12"></property>
<property name="salary" value="14000.0"></property>
</bean>
1:执行构造器,创建对象
2:创建对象之后,调用有@PostContruct注解的方法初始化bean对象
3:调用afterProptertiesSeet方法初始化对象 这里创建完对象之后,有一个set注入的过程,会调用Emp类中的set*方法,对对象进行初始化,然后
在调用2,3步骤。 假如把Emp对象中set方法注释,那么第2条语句执行完创建对象之后,就会停止。 三:注入List<接口> 对象
如果在一个类里面需要依赖多个bean对象时,可以通过实现接口的方式,将所有的bean注入,方式如下:
/**
* @author Administrator
* IBusinessService接口是一个空接口,作为一个标记
*/
public interface IBusinessService {
public abstract void execute();
}

  

/**
* @author Administrator
*
*/
@Component
public class ABusinessServiceImpl implements IBusinessService{ @Override
public void execute() {
System.out.println("ABusinessServiceImpl...");
} }

  

@Component
public class BBusinessServiceImpl implements IBusinessService{
@Override
public void execute() {
System.out.println("BBusinessServiceImpl...");
}
}

  

@Component
public class CBusinessServiceImpl implements IBusinessService{
@Override
public void execute() {
System.out.println("CBusinessServiceImpl...");
}
}

  

在*handler类中依赖上面3个类

@Component
public class BusinessServiceHandler { @Autowired
private List<IBusinessService> services; public void handler(){
for(IBusinessService s:services){
s.execute();
}
}
}

  

测试注入效果:

@Test
public void testAppContext() {
String conf = "applicationContext.xml";
ApplicationContext context = new ClassPathXmlApplicationContext(conf);
BusinessServiceHandler bhandler = ApplicationContextUtils.getBean("businessServiceHandler");
bhandler.handler();
}

  

ABusinessServiceImpl...
BBusinessServiceImpl...
CBusinessServiceImpl...

  

执行成功!

												

spring扩展的常用接口的更多相关文章

  1. spring4.1.8扩展实战之四:感知spring容器变化(SmartLifecycle接口)

    本章是<spring4.1.8扩展实战>的第四篇,如果业务上需要在spring容器启动和关闭的时候做一些操作,可以自定义SmartLifecycle接口的实现类来扩展,本章我们通过先分析再 ...

  2. spring扩展点之四:Spring Aware容器感知技术,BeanNameAware和BeanFactoryAware接口,springboot中的EnvironmentAware

    aware:英 [əˈweə(r)] 美 [əˈwer] adj.意识到的;知道的;觉察到的 XXXAware在spring里表示对XXX感知,实现XXXAware接口,并通过实现对应的set-XXX ...

  3. spring扩展点整理

    本文转载自spring扩展点整理 背景 Spring的强大和灵活性不用再强调了.而灵活性就是通过一系列的扩展点来实现的,这些扩展点给应用程序提供了参与Spring容器创建的过程,好多定制化的东西都需要 ...

  4. CSharpGL(2)设计和使用场景元素及常用接口

    CSharpGL(2)设计和使用场景元素及常用接口 2016-08-13 由于CSharpGL一直在更新,现在这个教程已经不适用最新的代码了.CSharpGL源码中包含10多个独立的Demo,更适合入 ...

  5. Servlet API遍程常用接口和类

    本文主要总结Servlet  API遍程常用接口和类 Servlet API http://tomcat.apache.org/tomcat-5.5-doc/servletapi/index.html ...

  6. spring中的aware接口

    1.实现了相应的aware接口,这个类就获取了相应的资源. 2.spring中有很多aware接口,包括applicationContextAware接口,和BeanNameAware接口. 实现了这 ...

  7. Hibernate常用接口

    Hibernate的接口类型 在了解了Hibernate的基本配置,映射文件后,道路已经铺平了.我们继续往前走.接下来,我们应该做的是了解Hibernate常用的接口,对Hibernate的工作方式进 ...

  8. JDBC数据库编程常用接口(转)

    JDBC的全称是Java DataBase Connectivity,是一套面向对象的应用程序接口(API),制定了统一的访问各种关系数据库的标准接口,为各个数据库厂商提供了标准接口的实现.这东西能够 ...

  9. 常用接口简析1---IEnumerable、IEnumerator简析

    常用接口的解析(链接) 1.IEnumerable深入解析 2.IComparable.IComparable接口解析 3.IList.IList接口解析      引言: IEnumerable和I ...

随机推荐

  1. 机器学习笔记(6):多类逻辑回归-使用gluon

    上一篇演示了纯手动添加隐藏层,这次使用gluon让代码更精减,代码来自:https://zh.gluon.ai/chapter_supervised-learning/mlp-gluon.html f ...

  2. 手机号是SIM卡的号呢,还是买手机时就带的

    可以用原来的号码!把原来的卡装在新手机里就可以了,你的号码没有改变! 手机的号是由sim卡来决定的! 但是卡上的号码显示的是卡的一些信息! 你不用去理会它! 全文:http://iask.sina.c ...

  3. AngularJS中获取数据源的几种方式

    在AngularJS中,可以从$rootScope中获取数据源,也可以把获取数据的逻辑封装在service中,然后注入到app.run函数中,或者注入到controller中.本篇就来整理获取数据的几 ...

  4. NVIDIA-docker报错:docker-ce (= 5:18.09.0~3-0~ubuntu-xenial) but 18.06.0~ce~3-0~ubuntu is to be installed

    报错: The following packages have unmet dependencies: nvidia-docker2 : Depends: docker-ce (= 5:18.09.0 ...

  5. 最近IOS10.2.1 iphone6 无法通过appStore 来更新 下载任何APP。好烦啊。

    今天打开爱思助手,查看事实日志,发现了原因: Mar :: iPhone6 appstored(StoreServices)[] <Notice>: SSSQLiteDatabase: C ...

  6. 奇怪吸引子---RayleighBenard

    奇怪吸引子是混沌学的重要组成理论,用于演化过程的终极状态,具有如下特征:终极性.稳定性.吸引性.吸引子是一个数学概念,描写运动的收敛类型.它是指这样的一个集合,当时间趋于无穷大时,在任何一个有界集上出 ...

  7. 【Yaml】Yaml学习笔记

    转载:https://blog.csdn.net/moshenglv/article/details/52084899 YAML何许物也?在XML泛滥的情况下,YAML的出现的确让人眼前一亮,在初步学 ...

  8. Spring Cloud Netflix Eureka源码导读与原理分析

    Spring Cloud Netflix技术栈中,Eureka作为服务注册中心对整个微服务架构起着最核心的整合作用,因此对Eureka还是有很大的必要进行深入研究. 本文主要分为四部分,一是对项目构建 ...

  9. 【阿里巴巴Java开发手册——集合处理】13.集合的稳定性(order)和有序性(sort)

    有序性(sort):指遍历的结果是按照某种比较规则依次排列的. 稳定性(order):指集合每次遍历的元素的次序是一定的. 如:ArrayList是order/unsort HashMap是unord ...

  10. excel表格 xls、xlsx 读取

    public static void main(String[] args) throws Exception { // getdslContext(); String file = "F: ...