`
lan_qie
  • 浏览: 12535 次
社区版块
存档分类
最新评论

利用spring扩展点代理bean的简单示例

阅读更多

BeanPostProcessor扩展点有两个方法:
1、在bean属性装配完成,执行完各种Aware之后,InitializingBean和init-method方法之前调用,返回的对象将替换原来的bean
Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
2、InitializingBean和init-method方法执行之后调用,返回的对象将替换原来的bean,可以完成一些代理之类的工作
Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;

利用这个扩展点的postProcessAfterInitialization方法,可以完成对指定bean的代理

public class TimerFilter4Spring implements BeanPostProcessor {
	private final Logger logger = LoggerFactory.getLogger(this.getClass());

	private boolean isProxy = false;
	private boolean canUseCglib = false;
	private List<String> beanNames;
	private List<String> classNames;

	private List<Pattern> beanNamePattern = new ArrayList<Pattern>();
	private List<Class<?>> classs = new ArrayList<Class<?>>();

	@Override
	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}

	@SuppressWarnings("rawtypes")
	@Override
	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		if (isProxy) {
			if (this.containClass(bean) && this.containBeanName(beanName)) {
				if (bean.getClass().isInterface()) {
					Class[] interfaces = bean.getClass().getInterfaces();
					this.logger.info("TimerFilter4Spring(" + beanName + ") add to jdk proxy!");
					return Proxy.newProxyInstance(bean.getClass().getClassLoader(), interfaces,
							new TimerFilterInvocationHandler(bean, beanName));
				} else if (canUseCglib) {
					Enhancer enhancer = new Enhancer();
					enhancer.setSuperclass(bean.getClass());
					enhancer.setCallback(new TimerFilterInvocationHandler(bean, beanName));
					return enhancer.create();
				}
			}
		}
		return bean;

	}

	private boolean containBeanName(String beanName) {
		if (this.beanNamePattern != null && !this.beanNamePattern.isEmpty()) {
			for (Pattern pattern : this.beanNamePattern) {
				Matcher matcher = pattern.matcher(beanName);
				if (matcher.find()) {
					return true;
				}
			}
		} else {// 空表示全需要替换
			return true;
		}
		return false;
	}

	private boolean containClass(Object bean) {
		if (this.classs != null && !this.classs.isEmpty()) {
			for (Class<?> claz : this.classs) {
				if (claz.isInstance(bean)) {
					return true;
				}
			}
		} else {// 空表示全需要替换
			return true;
		}
		return false;
	}

	public void setIsProxy(boolean isProxy) {
		this.isProxy = isProxy;
	}

	public void setCanUseCglib(boolean canUseCglib) {
		this.canUseCglib = canUseCglib;
	}

	public void setBeanNames(List<String> beanNames) {
		this.beanNames = beanNames;
		if (this.beanNames != null && !this.beanNames.isEmpty()) {
			for (String str : this.beanNames) {
				str = StringUtils.trimToEmpty(str);
				if (StringUtils.isNotEmpty(str)) {
					try {
						this.beanNamePattern.add(Pattern.compile(str));
						this.logger.info(str + " add to TimerFilter4Spring.beanNamePattern success!");
					} catch (Exception e) {
						this.logger.error(str + " add to TimerFilter4Spring.beanNamePattern failure!", e);
					}
				}
			}
		}
	}

	public void setClassNames(List<String> classNames) {
		this.classNames = classNames;
		if (this.classNames != null && !this.classNames.isEmpty()) {
			for (String str : this.classNames) {
				str = StringUtils.trimToEmpty(str);
				if (StringUtils.isNotEmpty(str)) {
					try {
						this.classs.add(Class.forName(str));
						this.logger.info(str + " add to TimerFilter4Spring.classs success!");
					} catch (Exception e) {
						this.logger.error(str + " add to TimerFilter4Spring.classs failure!", e);
					}
				}
			}
		}
	}

	private class TimerFilterInvocationHandler implements InvocationHandler, MethodInterceptor {
		private Object target;

		// private String beanName;

		public TimerFilterInvocationHandler(Object target, String beanName) {
			this.target = target;
			// this.beanName = beanName;
		}

		@Override
		public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
			return this.doInvoke(this.target, args, method, null);
		}

		@Override
		public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
			return this.doInvoke(this.target, args, method, proxy);
		}

		private Object doInvoke(Object targetObj, Object[] args, Method method, MethodProxy proxy) throws Throwable {
			Throwable failed = null;
			Object result = null;
			try {
				// TODO 方法调用前
				if (proxy != null) {
					result = proxy.invoke(this.target, args);
				} else if (method != null) {
					result = method.invoke(this.target, args);
				}
				// TODO 方法调用后
			} catch (Throwable e) {
				failed = e;
				// TODO catch中
			} finally {
				System.out.println();
				// TODO finally中
			}

			if (failed != null) {
				throw failed;
			}
			return result;
		}

	}
}
 

 


上面这个过程是spring对xml配置方式使用aop的基本原理,当然spring对切入点、要代理的bean等的配置非常灵活,但是对xml配置方式的aop核心实现大概是这样,具体实现在org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator中


分享到:
评论

相关推荐

    spring扩展点测试示例代码

    这个压缩包提供的"spring扩展点测试示例代码"是一个实例,帮助我们理解如何在实践中利用Spring的扩展点进行自定义功能的实现。 首先,Spring的核心设计理念之一就是“依赖注入”(Dependency Injection,DI),它...

    spring简单示例

    综上所述,"spring简单示例"可能会涵盖Spring框架的基本配置、Bean管理、依赖注入、AOP、数据访问、Web开发以及测试等方面的内容。通过学习和实践这些示例,你可以更好地理解和掌握Spring框架的应用。

    spring3零配置注解实现Bean定义

    标题《spring3零配置注解实现Bean定义》中蕴含的知识点主要包括Spring框架中的Bean定义配置方法的演进,特别是从Spring 2.5到Spring 3版本的过渡过程中,对于注解方式实现Bean定义的支持如何被引入和优化。...

    Spring3.2.1MVC+Freemarker简单示例

    在本文中,我们将深入探讨如何使用Spring 3.2.1 MVC框架与Freemarker模板引擎结合,构建一个简单的Web应用程序。Spring MVC是Spring框架的一部分,它为开发RESTful Web服务提供了强大的支持,而Freemarker则是一个轻...

    Spring示例

    最后,Spring Cloud扩展了Spring的功能,提供了服务发现、配置中心、负载均衡、熔断机制等微服务治理工具,帮助企业构建云原生应用。 总结起来,"Spring示例"可能涵盖了Spring框架的多个方面,包括IoC、AOP、测试、...

    Spring示例代码

    Bean工厂是Spring中对象的容器,而应用上下文则扩展了Bean工厂,提供了更多的企业级服务。 2. **数据访问/集成**:支持JDBC、ORM(Object-Relational Mapping)框架如Hibernate和MyBatis,以及OXM(Object-XML ...

    spring 的动态代理详解

    Spring框架利用动态代理技术为Bean提供了横切关注点(如事务管理、日志记录等)的集成方式,这极大地简化了应用程序的开发过程。本文将深入探讨Spring中动态代理的机制、关键概念以及其实现细节。 #### 动态代理...

    Spring3+Spring-data-mongodb1.5.6示例

    Spring Data MongoDB是Spring Data项目的一部分,它提供了一个面向对象的API,使得与NoSQL数据库MongoDB进行交互变得更加简单。以下是关于这个主题的详细知识点: 1. **Spring Framework**: Spring是一个开源的应用...

    spring quartz 整合示例

    这个压缩包文件提供了一个实际的示例,用于演示如何在Spring应用中集成Quartz进行任务调度。下面将详细解释其中涉及的知识点。 首先,Quartz是一个开源的作业调度框架,它允许开发者创建、调度和管理重复的任务。在...

    Spring AOP 1.0示例

    通过这个示例,我们可以看到Spring AOP 1.0如何帮助我们实现日志记录这一横切关注点。在实际项目中,我们可以根据需要扩展切面,以处理更多类型的关注点,如事务管理和缓存控制。Spring AOP的这种模块化设计极大地...

    XFire和Spring整合的完整示例

    同时,Spring提供了一个`XFireClientProxyFactoryBean`,可以用来创建客户端代理,消费远程服务。 4. **依赖注入** Spring的DI允许我们在服务实现类中注入依赖,比如DAO层的对象,以实现业务逻辑。这使得服务的...

    Spring集成Quartz的代码示例

    在实际项目中,你可能还需要处理任务的并发控制、异常处理、任务的持久化等问题,这些都可以通过Quartz提供的API和Spring的扩展点进行定制。在压缩包文件`com.cayden.springquartz.test`中,可能包含了上述步骤的...

    activemq+spring demo 简单示例

    本`activemq+spring demo`简单示例旨在帮助开发者理解如何在`Spring`环境中集成和使用`ActiveMQ`。通过这个示例,我们可以学习到以下关键知识点: 1. **ActiveMQ的基本概念**:`ActiveMQ`作为消息中间件,负责在...

    spring.net整合mvc小示例

    在本示例中,我们将探讨如何将Spring.NET与ASP.NET MVC框架整合,以实现更灵活、可维护的Web应用程序。 1. **依赖注入(Dependency Injection,DI)**: 依赖注入是Spring.NET的核心特性,它允许我们解耦组件间的...

    Spring笔记示例源代码

    "Spring笔记示例源代码"这个资源很可能是为了帮助学习者深入理解Spring框架的各种功能和用法而提供的实际代码示例。 1. **Spring IoC**:IoC是Spring的核心特性,它将对象的创建和管理权交给Spring容器,使得开发者...

    spring 学习 springcore例子

    Spring框架是Java开发中的核心组件,它以依赖注入(Dependency Injection,DI)和面向切面编程(Aspect-...通过创建和配置Bean,理解DI的工作原理,以及如何利用Spring提供的各种功能来构建可扩展和可维护的应用程序。

    spring代理实现项目

    总结,"spring代理实现项目"主要涉及到的是Spring的AOP特性,包括静态代理和动态代理的运用,以及如何通过代理模式来实现如事务管理等跨切面关注点。在项目中,我们可以通过阅读和分析源码,理解Spring如何根据不同...

    spring famework 示例

    这个示例项目显然旨在演示如何利用Maven构建工具来搭建和管理Spring框架的应用。 Maven是Apache软件基金会开发的一款项目管理和集成工具,它通过一个统一的构建过程和项目信息管理,帮助开发者更有效地处理项目依赖...

    maven + spring mvc整合示例代码下载.zip

    【标题】:“maven + spring mvc整合示例代码下载.zip”是一个包含使用Maven构建并集成Spring MVC框架的示例项目的压缩包。这个项目旨在帮助开发者理解和实践如何在Java Web开发中结合这两个强大的工具。 【描述】...

Global site tag (gtag.js) - Google Analytics