一: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. java给时间格式化

    package com.apress.springrecipes.sequence; import java.text.DateFormat;import java.text.SimpleDateFo ...

  2. git配置SSH Key,上传本地代码至github

    git配置全局的name和email git config --global user.name "name" git config --global user.email &qu ...

  3. Codeforces Round #532 (Div. 2)

    Codeforces Round #532 (Div. 2) A - Roman and Browser #include<bits/stdc++.h> #include<iostr ...

  4. iptables为什么需要增加loopback回环的规则

    先说loopback回环的大致个人理解: 1.lo的主要作用是基于本地访问本地的数据包会经过lo这张网卡. 2.比如ping 127.0.0.1时,你在eth0抓不到,只能在lo这张网卡捕获. 再来看 ...

  5. [Python] 抓取时光网的电影列表并生成网页

    抓取时光网的电影列表并生成网页 源码 https://github.com/YouXianMing/BeautifulSoup4-WebCralwer 分析 利用BeautifulSoup进行分析网页 ...

  6. Linux 保护文件 不给修改

    chatter +i  file 文件不能删除,不能更改,不能移动 chatter -i  file  恢复 lsattr file 查看 ----i--------e-- file 修改会提示: f ...

  7. Android批量图片加载经典系列——使用LruCache、AsyncTask缓存并异步加载图片

    一.问题描述 使用LruCache.AsyncTask实现批量图片的加载并达到下列技术要求 1.从缓存中读取图片,若不在缓存中,则开启异步线程(AsyncTask)加载图片,并放入缓存中 2.及时移除 ...

  8. AutoMapperExtension

    using System; using System.Collections.Generic; using System.Linq; using AutoMapper; using System.Co ...

  9. ionic 布局

    1. row col 设置自动换行 <!--长文本换行 item-text-wrap--> <li class="item item-text-wrap" ng- ...

  10. mysql常用的一些修改命令

    修改表字段名称: alter table  table_name change column column_name_old  column_name_new column_type; mysql注释 ...