一: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. apache hive 1.0.0发布

    直接从0.14升级到1.0.0,主要变化有: 去掉hiveserver 1 定义公共的API,比如HiveMetaStoreClient 当然,也需要使用新的beeline cli客户端. 不过最值得 ...

  2. Winform 打包 混淆 自动更新

    路径: 最终的解决方案是,ConfuserEx+Installshield+AutoUpdater.NET,ConfuserEx做代码混淆工作,Installshield可以解决注册表的问题,Auto ...

  3. c# sqlite 数据库加密

    c# sqlite 数据库加密 2010-05-29 10:55 用了ADO.NET 2.0 SQLite Data Provider这样可以直接利用它来创建一个加密的sqlite数据库.有关c#代码 ...

  4. 8-06. 畅通project之局部最小花费问题(35)(最小生成树_Prim)(ZJU_PAT)

    题目链接:http://pat.zju.edu.cn/contests/ds/8-06 某地区经过对城镇交通状况的调查.得到现有城镇间高速道路的统计数据,并提出"畅通project" ...

  5. java实现在线浏览zip文件及文件下载

    应用背景:我们知道压缩文件中某一个文件的名字,只想下载这个文件而不下载整个压缩文件. 先来看一上QQ邮箱的附件浏览: 以下是我们第一个版本的: 业务逻辑中还要判读用户是否有此文件的防问权限 2017- ...

  6. 给你的 CentOS 7 安装中文支持

    今天给大家分享个给 CentOS 7 安装中文支持的方法,所谓“中文支持”目前明月观测到的是指命令行提示支持中文提示显示,还有就是 Vim 启动后看到的也是有中文提是的界面包括 Vim 内各种提示也会 ...

  7. C# ConcurrentBag实现

    ConcurrentBag可以理解为是一个线程安全无序集合,API比我们的list要弱一点,那我们来看看它的实现: public class ConcurrentBag<T> : IPro ...

  8. 几种php加速器比较

    一.PHP加速器介绍 PHP加速器是一个为了提高PHP执行效率,从而缓存起PHP的操作码,这样PHP后面执行就不用解析转换了,可以直接调用PHP操作码,这样速度上就提高了不少. Apache中使用mo ...

  9. he canvas has been tainted by cross-origin data and tainted canvases may not be exported

    来自: https://ourcodeworld.com/articles/read/182/the-canvas-has-been-tainted-by-cross-origin-data-and- ...

  10. git的使用笔记

    1.git下载:https://git-scm.com/downloads   安装git   2.在github.com网站上注册账号 网址:https://github.com/   3.使用gi ...