lookup方法注入
场景:想通过MagicBoss.getCar方法每次都得到一个新的car实例。car是prototype,但magicBoss是singleton。可以采用lookup方法注入。依赖于Cglib。Cglib可以在运行期动态操作字节码,为Bean动态创建子类或实现类。
public interface MagicBoss{
Car getCar();
}
<bean id="car" class="x.x.Car"/>
<bean id="magicBoss" class="x.x.magicBoss">
<lookup-method name="getCar" bean="car"/>
</bean>
bean之间的关系
- 通过bean的parent,abstract属性实现继承
- 通过bean的depends-on属性实现依赖。
web环境相关的作用域
如果要使用与web环境相关的作用域,则需要在web.xml中配置一个RequestContextListener监听器。
FactoryBean
spring提供了一个FactoryBean接口,用户可以通过实现该工厂类接口定制实例化Bean的逻辑。它提供了三个方法:
- T getObject():返回由FactoryBean创建的Bean实例,如果isSingleton()返回true,该实例会被放到spring容器的缓存池中。
- isSingleton():是否是单实例。
- Class
扫描过滤
<context:component-scan/>
有一个use-default-filters属性,默认为true,表示扫描@Component,@Controller,@Service,@Repository.
对集合类进行标注
如果对类中集合类进行@Autowired标注,那么spring会将容器中所有类型匹配的Bean自动注入进来。
Autowired
private List<Plugin> plugins;
Autowired
private Map<String,Plugin> pluginMaps;//spring4.0提供的新特性。key为Bean的名字
@Component
@Order(value=1)//值越小,优先被加载
public Class OnePlugin implements Plugin{
}
容器事件
java通过java.util.EventObject和EventListener接口描述事件和监听器。在事件体系中,除了事件和监听器外,还有事件源,事件监听器注册表,事件广播器。
spring事件类结构:
1. ApplicationEvent的构造函数public ApplicationEvent(Object source) 。通过source指定事件源,他有两个子类。
- ApplicationContextEvent:容器事件,拥有四个子类,分贝代表容器启动,刷新,停止以及关闭的事件。
- RequestHandleEvent:当一个Http请求被处理后,产生该事件。拥有两个子类,分别代表Servlet及Portlet的请求事件。
可以根据需要扩展ApplicationEvent定义自己的事件。完成其它特殊的功能。
- 事件监听器接口
ApplicationListener接口只定义了一个方法,onApplicationEvent(E Event),在该方法中编写事件的响应逻辑。 SmartApplicationListener定义了两个方法:
boolean supportsEventType(Class<? extends ApplicationEvent> eventType);
boolean supportsSourceType(Class<?> sourceType);
GenericApplicationListener是4.2新增的,增强了对泛型事件的支持。
boolean supportsEventType(ResolvableType eventType);
boolean supportsSourceType(Class<?> sourceType);
- 事件广播器
spring事件体系的具体实现
ApplicationContext的抽象实现类AbstractApplicationContext完成了事件体系的搭建。他拥有一个applicationEventMulticaster成员变量,在refresh方法中有以下3个步骤
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
//注册监听器
registerListeners();
//完成刷新并发布容器刷新事件
finishRefresh();
示例
public class MailSenderEvent extends ApplicationContextEvent{
private String to;
public MailSenderEvent(ApplicationContext source,String to) {
super(source);
this.to = to;
}
public String getTo(){
return to;
}
}
public class MailSenderListener implements ApplicationListener<MailSenderEvent>{
@Override
public void onApplicationEvent(MailSenderEvent event) {
MailSenderEvent mse = event;
System.out.println("mailsender向"+mse.getTo()+"send a letter");
}
}
ublic class MailSender implements ApplicationContextAware{
private ApplicationContext ctx;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.ctx = applicationContext;
}
public void sendMail(String to){
System.out.println("模拟发送邮件");
MailSenderEvent mSenderEvent = new MailSenderEvent(this.ctx, to);
ctx.publishEvent(mSenderEvent);//发布事件
}
}
<bean class="x.x.MailSenderListener"/>
<bean id="mailSender" class="x.x.MailSender"/>