Spring里用的最经典的一个设计模式就是:模板方法模式
让一个对象的创建不用new了,可以自动的生产,这其实就是利用java里的反射,反射其实就是在运行时动态的去创建、调用对象,Spring就是在运行时,跟xml Spring的配置文件来动态的创建对象,和调用对象里的方法的 。
Spring还有一个核心就是AOP这个就是面向切面编程,可以为某一类对象 进行监督和控制
接下来重点介绍IOC的动态获取
IoC(Inversion of control): 控制反转
控制权由对象本身转向容器;由容器根据配置文件或者注解去创建实例并创建各个实例之间的依赖关系
核心:bean工厂;在Spring中,bean工厂创建的各个实例称作bean ,交给spring管理
自己写了一个工具类实现ApplicationContextAware接口,并将这个加入到spring的容器
通过这个实例来获取一个已经注入了的bean.全项目类中都能获取到
首先新建类ApplicationContextHolderGm实现ApplicationContextAware,DisposableBean 接口
加静态 属性private static ApplicationContext applicationContext;
重写setApplicationContext这个方法
@SuppressWarnings("all") public void setApplicationContext(ApplicationContext context) throws BeansException { if (this.applicationContext != null) { throw new IllegalStateException("ApplicationContextHolderGm already holded 'applicationContext'."); } this.applicationContext = context; log.info("holded applicationContext,显示名称:" + applicationContext.getDisplayName());
}
ApplicationContext这个是接口 继承了 EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,
MessageSource, ApplicationEventPublisher, ResourcePatternResolver等接口
其中MessageResource接口,使用getMessage()的各个方法来取得信息资源
最主要就是 资源管理:可以直接读取一个文件的内容(getResource)
web框架中(加入一个servlet或监听器)和事件处理
/** * 根据bean的id来查找对象 * @param id * @return */ public static Object getBeanById(String id){ checkApplicationContext(); //检查ApplicationContext不为空. return applicationContext.getBean(id);
}
/** * 通过名称获取bean * @param name * @return */ @SuppressWarnings("unchecked") public static <T> T getBean(String name){ checkApplicationContext(); Object object = applicationContext.getBean(name); return (T)object;
}
/** * 根据bean的class来查找对象 * @param c * @return */ @SuppressWarnings("all") public static <T> T getBeanByClass(Class<T> c){ checkApplicationContext(); return (T)applicationContext.getBean(c);
}
以下是获取类
import java.util.Map;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.BeansException;import org.springframework.beans.factory.DisposableBean;import org.springframework.context.ApplicationContext;import org.springframework.context.ApplicationContextAware;/** * 写一个工具类实现ApplicationContextAware接口,并将这个加入到spring的容器 * ApplicationContextHolderGm.getBean("xxxDao"); * 通过这个实例来获取一个已经注入了的bean. * @author jiayi * */public class ApplicationContextHolderGm implements ApplicationContextAware,DisposableBean{ private static Logger log = LoggerFactory.getLogger(ApplicationContextHolderGm.class); private static ApplicationContext applicationContext; @SuppressWarnings("all") public void setApplicationContext(ApplicationContext context) throws BeansException { if (this.applicationContext != null) { throw new IllegalStateException("ApplicationContextHolderGm already holded 'applicationContext'."); } this.applicationContext = context; log.info("holded applicationContext,显示名称:" + applicationContext.getDisplayName()); } /**获取applicationContext对象*/ public static ApplicationContext getApplicationContext() { if (applicationContext == null) { throw new IllegalStateException( "'applicationContext' property is null,ApplicationContextHolder not yet init."); } return applicationContext; } /** * 根据bean的id来查找对象 * @param id * @return */ public static Object getBeanById(String id){ checkApplicationContext(); return applicationContext.getBean(id); } /** * 通过名称获取bean * @param name * @return */ @SuppressWarnings("unchecked") public static <T> T getBean(String name){ checkApplicationContext(); Object object = applicationContext.getBean(name); return (T)object; } /** * 根据bean的class来查找对象 * @param c * @return */ @SuppressWarnings("all") public static <T> T getBeanByClass(Class<T> c){ checkApplicationContext(); return (T)applicationContext.getBean(c); } /** * 从静态变量ApplicationContext中取得Bean, 自动转型为所赋值对象的类型. * 如果有多个Bean符合Class, 取出第一个. * @param cluss * @return */ public static <T> T getBean(Class<T> cluss){ checkApplicationContext(); return (T)applicationContext.getBean(cluss); } /** * 名称和所需的类型获取bean * @param name * @param cluss * @return */ public static <T> T getBean(String name,Class<T> cluss){ checkApplicationContext(); return (T)applicationContext.getBean(name,cluss); } public static <T> Map<String,T> getBeansOfType(Class<T> type) throws BeansException{ checkApplicationContext(); return applicationContext.getBeansOfType(type); } /** * 检查ApplicationContext不为空. */ private static void checkApplicationContext() { if (applicationContext == null) { throw new IllegalStateException("applicaitonContext未注入,请在applicationContext.xml中定义ApplicationContextHolderGm"); } } @Override public void destroy() throws Exception { checkApplicationContext(); } /** * 清除applicationContext静态变量 */ public static void cleanApplicationContext(){ applicationContext = null; } }
使用的话直接getbean("bean.class") 即可 ,前提是类必须交由spring管理
例如
@Component
public class LogEventController{
}
/** * 记录用户操作日志 */protected void recordOperateLog(String log,int isSucc) { synchronized(lock){ ApplicationContextHolderGm.getBean(LogEventController.class).post(UserEvent.valueOf(getSessionInfo(), log,isSucc)); }
}
ApplicationContextHolderGm.getBean(LogEventController.class)获取到的bean;