Spring_Spring与IoC_Bean的装配
一、Bean的装配
bean的装配,即Bean对象的创建,容器根据代码要求来创建Bean对象后再传递给代码的过程,称为Bean的装配。
二、默认装配方式
代码通过getBean()方式从容器获取指定的Bean示例,容器首先会调用Bean类的无参构造器,创建空值的示例对象。
三、工厂方法设计模式(为了解耦合)
public class ServiceFactory {
public ISomeService getISomeService(){
return new SomeServiceImpl();
}
}
@Test
public void test01() {
ISomeService service=new ServiceFactory().getISomeService();
service.doSome();
}
静态工厂
public class ServiceFactory {
public static ISomeService getISomeService(){
return new SomeServiceImpl();
}
}
@Test
public void test01() {
ISomeService service=ServiceFactory.getISomeService();
service.doSome();
}
四、动态工厂Bean
public class ServiceFactory {
public ISomeService getSomeService(){
return new SomeServiceImpl();
}
}
<!--注册动态工厂 -->
<bean id="factory" class="com.jmu.ba02.ServiceFactory"></bean>
@SuppressWarnings("resource")
@Test
public void test02() {
//创建容器对象
String resource = "com/jmu/ba02/applicationContext.xml";
ApplicationContext ac=new ClassPathXmlApplicationContext(resource);
ServiceFactory factory=(ServiceFactory) ac.getBean("factory");
ISomeService service = factory.getSomeService();
service.doSome();
}
但以上方法不好。修改如下(测试类看不到工厂,也看不到接口的实现类)
<!--注册service:动态工厂Bean-->
<bean id="myService" factory-bean="factory" factory-method="getSomeService"></bean>
@SuppressWarnings("resource")
@Test
public void test02() {
//创建容器对象
String resource = "com/jmu/ba02/applicationContext.xml";
ApplicationContext ac=new ClassPathXmlApplicationContext(resource);
ISomeService service = (ISomeService) ac.getBean("myService");
service.doSome();
}
五、静态工厂Bean
public class ServiceFactory {
public static ISomeService getSomeService(){
return new SomeServiceImpl();
}
}
<!--注册动态工厂 :静态工厂Bean-->
<bean id="myService" class="com.jmu.ba03.ServiceFactory" factory-method="getSomeService"></bean>
@Test
@SuppressWarnings("resource")
public void test02() {
//创建容器对象
String resource = "com/jmu/ba03/applicationContext.xml";
ApplicationContext ac=new ClassPathXmlApplicationContext(resource);
ISomeService service = (ISomeService) ac.getBean("myService");
service.doSome();
}
六、Bean的装配
1、Singleton单例模式:


2、原型模式prototype:



3、request:对于每次HTTP请求,都会产生一个不同的Bean实例
4、Session:对于每次不同的HTTP session,都会产生一个不同的Bean实例
七、Bean后处理器
bean后处理器是一种特殊的Bean,容器中所有的Bean在初始化时,均会自动执行该类的两个方法,由于该Bean是由其他Bean自动调用执行,不是程序员手动创建,所有Bean无需id属性。
需要做的是,在Bean后处理器类方法中,只要对Bean类与Bean类中的方法进行判断,就可以实现对指定的Bean的指定方法进行功能扩展和增强。方法返回的Bean对象,即是增强过的对象。
代码中需要自定义Bean后处理下类,该类就是实现了接口BeanPostProcessor的类。该接口包含2个方法,分别在目标Bean初始化完毕之前和之后执行,它们的返回值为:功能被扩展或增强后的Bean对象。
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor; public class MyBeanPostProcessor implements BeanPostProcessor {
//bean:表示当前正在进行初始化的Bean对象
//beanName:表示当前正在进行初始化的Bean对象的id
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
// TODO Auto-generated method stub
System.out.println("执行before");
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
// TODO Auto-generated method stub
System.out.println("执行after");
return bean;
} }
MyBeanPostProcessor
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="myService" class="com.jmu.ba05.SomeServiceImpl"></bean>
<!--注册bean后处理器 -->
<bean class="com.jmu.ba05.MyBeanPostProcessor"></bean>
</beans>
applicationContext.xml
输出:
执行doSome()方法
log4j:WARN No appenders could be found for logger (org.springframework.core.env.StandardEnvironment).
log4j:WARN Please initialize the log4j system properly.
执行before
执行after
执行doSome()方法
输出
八、Bean后处理器的应用
要求:增强service的doSome()
public interface ISomeService {
String doSome();
String doOther();
}
ISomeService
public class SomeServiceImpl implements ISomeService {
@Override
public String doSome() {
// TODO Auto-generated method stub
System.out.println("执行doSome()方法");
return "abcd";
}
@Override
public String doOther() {
// TODO Auto-generated method stub
System.out.println("执行doOther()方法");
return "fight";
}
}
SomeServiceImpl
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy; import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor; public class MyBeanPostProcessor implements BeanPostProcessor {
//bean:表示当前正在进行初始化的Bean对象
//beanName:表示当前正在进行初始化的Bean对象的id
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
// TODO Auto-generated method stub
System.out.println("执行before");
return bean;
}
@Override
public Object postProcessAfterInitialization(final Object bean, String beanName) throws BeansException {
// TODO Auto-generated method stub
System.out.println("执行after");
if ("myService".equals(beanName)) {
Object obj = Proxy.newProxyInstance(bean.getClass().getClassLoader(), bean.getClass().getInterfaces(),
new InvocationHandler() { @Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object invoke = method.invoke(bean, args);
if ("doSome".equals(method.getName())) {
// TODO Auto-generated method stub
return ((String) invoke).toUpperCase();
}
return invoke;
}
});
//类加载器:bean.getClass().getClassLoader()
//final:内部类使用外部类的成员变量,外部成员变量需要为fianl
return obj;
}
return bean;
} }
MyBeanPostProcessor
<bean id="myService" class="com.jmu.ba05.SomeServiceImpl"></bean>
<bean id="myService2" class="com.jmu.ba05.SomeServiceImpl"></bean>
<!--注册bean后处理器 -->
<bean class="com.jmu.ba05.MyBeanPostProcessor"></bean>
applicationContext.xml
@SuppressWarnings("resource")
@Test
public void test02() {
//创建容器对象
String resource = "com/jmu/ba05/applicationContext.xml";
ApplicationContext ac=new ClassPathXmlApplicationContext(resource);
ISomeService service=(ISomeService) ac.getBean("myService");
System.out.println(service.doSome());
System.out.println(service.doOther());
System.out.println("--------------------");
ISomeService service2=(ISomeService) ac.getBean("myService2");
System.out.println(service2.doSome());
System.out.println(service2.doOther());
}
MyTest
输出:
执行doSome()方法
log4j:WARN No appenders could be found for logger (org.springframework.core.env.StandardEnvironment).
log4j:WARN Please initialize the log4j system properly.
执行before
执行after
执行before
执行after
执行doSome()方法
ABCD
执行doOther()方法
fight
--------------------
执行doSome()方法
abcd
执行doOther()方法
fight
output
九、定制Bean的生命周期始末



十、id与name属性
name可以包含各种字符,id的命名必须以字母开头。
Spring_Spring与IoC_Bean的装配的更多相关文章
- 读取xml数据装配到字典中之应用场景
前段时间看到支付宝设置里面有个多语言这个功能,蛮有意思的,就想双休没事的话做个相关的demo玩玩,可是礼拜六被妹子拽出去玩了一天,来大上海有大半年了,基本没有出去玩过,妹子说我是超级宅男,也不带她出去 ...
- [spring]03_装配Bean
3.1 JavaBean 3.1.1 JavaBean 是什么 JavaBean 是一种JAVA语言写成的可重用组件. 为写成JavaBean,类必须是具体的和公共的,并且具有无参数的构造器. Jav ...
- Autofac 组件、服务、自动装配 《第二篇》
一.组件 创建出来的对象需要从组件中来获取,组件的创建有如下4种(延续第一篇的Demo,仅仅变动所贴出的代码)方式: 1.类型创建RegisterType AutoFac能够通过反射检查一个类型,选择 ...
- Spring bean依赖注入、bean的装配及相关注解
依赖注入 Spring主要提供以下两种方法用于依赖注入 基于属性Setter方法注入 基于构造方法注入 Setter方法注入 例子: public class Communication { priv ...
- 【译】Spring 4 自动装配、自动检测、组件扫描示例
前言 译文链接:http://websystique.com/spring/spring-auto-detection-autowire-component-scanning-example-with ...
- 隐式的bean发现与自动装配机制
使用beans.xml文件进行bean的创建和注入通常是可行的,但在便利性上Spring提供了更简单的方法--自动装配 接下来我们假设一个场景:我有若干播放器(MediaPlayer{CD播放器/MP ...
- 解决自定义Shiro.Realm扩展类不能用注解(@Resource或@Autowire)自动装配的问题
问题产生原因:加载Realm时其他Spring配置文件(xml)尚未加载,导致注入失败. 解决方法:编写一个设置类把注入工作提前完成. package com.xkt.shiro import org ...
- Spring学习记录(十一)---使用注解和自动装配
Spring支持用注解配置Bean,更简便. 上面的组件,是根据实际情况配的.比如写的一个类,是做业务处理的,那就用注解@Service表示服务层组件,以此类推.将整体分成不同部分. 要在xml加入c ...
- Spring学习记录(三)---bean自动装配autowire
Spring IoC容器可以自动装配(autowire)相互协作bean之间的关联关系,少写几个ref autowire: no ---默认情况,不自动装配,通过ref手动引用 byName---根据 ...
随机推荐
- [flask 优化] 由flask-bootstrap,flask-moment引起的访问速度慢的原因及解决办法
一周时间快速阅读了400页的<javascript基础教程>,理解了主要概念.虽然对jquery.ajax.json这些方法的运用还不熟练,但在理清了概念之后解决了一个很久之前的疑问. 我 ...
- robotframework文本类型的下拉框
对于下拉框定位和输入,这里主要遇到有两种类型的下拉选择. 其中一个类型是select-options格式,如图 这种方式的定位可以使用select from list by value或select ...
- Bootstrap 开关(switch)使用整理
1.在JS里根据指定的 1或者0 或者其它值让按钮变成 on 或者 off (通常需要根据数据库查询的结果初始化开关的状态) (--开关插件包 bootstrap-switch.min.js) < ...
- 使用JSCH框架通过跳转机访问其他节点
之前搞了套远程访问ssh进行操作的代码,最近有需求,需要通过一台跳转机才能访问目标服务.在网上搜了半天,也没找到比较好的例子,就自己翻阅了下JSCH的API.但是看的云里雾里的.联想了下,端口转发的原 ...
- CountDownLatch的实现原理
CountDownLatch是java并发包中辅助并发的工具类,目的是让并发运行的代码在某一个执行点阻塞,直到所有条件都满足,这里的条件就是调用countDown()方法,有点类似计数器的功能. 用法 ...
- Python学习之--socket
1.Socket概述 网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket.socket通常也称作"套接字",用于描述IP地址和端口,是一个 ...
- vue.js初学,笔记1,安装
最近学习vue.js,下面是笔记: 说明:因为npm安装插件是从国外服务器下载,受网络影响大,可能出现异常,如果npm的服务器在中国就好了,所以我们乐于分享的淘宝团队干了这事.来自官网:"这 ...
- NGUI_概述
序言:这是张三疯第一次开始NGUI插件的学习,刚开始学习,肯定有很多漏洞,后期会及时的补上的. 希望大家可以见谅,希望大佬多多指教. 一.什么是NGUI: NGUI是严格遵循KISS原则并用C#编写的 ...
- 剑指Offer面试题39(Java版):二叉树的深度
题目:输入一棵二叉树的根节点,求该数的深度. 从根节点到叶结点依次进过的结点(含根,叶结点)形成树的一条路径,最长路径的长度为树的深度. 比如.例如以下图的二叉树的深度为4.由于它从根节点到叶结点的最 ...
- C++简易list
list不同于vector.每一个节点的结构须要自行定义,迭代器属于双向迭代器(不是随即迭代器),也须要自行定义.和通用迭代器一样,list的迭代器须要实现的操作有:++.--.*.->.==. ...