一: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. C# 8.0的新的using语法——Using declarations

    我们在代码中经常使用using保障非托管资源的释放 static void Main(string[] args) { using (var options = Parse(args)) { if ( ...

  2. Jenkins配置基于角色的项目权限管理

    转自: http://www.cnblogs.com/gao241/archive/2013/03/20/2971416.html, 版权归原作者. 本文将介绍如何配置jenkins,使其可以支持基于 ...

  3. Chart-template

    ylbtech-Chart: 1.返回顶部 1-1. 2.返回顶部   3.返回顶部   4.返回顶部   5.返回顶部     6.返回顶部   7.返回顶部   8.返回顶部   9.返回顶部   ...

  4. tensorflow之数据读取探究(1)

    Tensorflow中之前主要用的数据读取方式主要有: 建立placeholder,然后使用feed_dict将数据feed进placeholder进行使用.使用这种方法十分灵活,可以一下子将所有数据 ...

  5. How to make PostgreSQL functions atomic?

    Question: How to make PostgreSQL functions atomic? Assume I have some PostgreSQL functions like the ...

  6. 用户人品预测大赛--getmax队--竞赛分享

     用户人品预测大赛--getmax队--竞赛分享  DataCastle运营 发表于 2016-3-24 14:49:32      533  0  0 答辩PPT  

  7. 解决Gerrit的git unpack error问题

    今天上午同事和我说neutron项目要换成全新的内部代码,原先仓库里的代码要全部废弃掉.于是我就简单地创建了一个空项目使用git push --force将其置空. 下午的时候,麻烦事情就来了,同事发 ...

  8. 内联汇编中的asm和__asm__

    基本的内联汇编代码: asm格式: asm("assembly code"):   使用替换的关键字: 如果必须的话,可以改变用于标识内联汇编代码段的关键字asm.ANSI C规范 ...

  9. 【PMP】变更流程图与说明

    点击下载viso原件 以下是变更流程说明: 1.团队成员判定不需要变更 发起人提出变更请求,团队成员对该变更进行分析与评估影响,通过判断后,如果决定不需要变,那么就编写反馈报告提交给相关方确认,相关方 ...

  10. Mac下用zsh

    最近好多实验要跑,有时候Finder切换来切换去,感觉还不如用terminal. Mac默认的shell是bash.所以说我其实今天才弄明白shell和terminal之间的关系.在人和计算机内核之间 ...