spring中BeanPostProcessor接口的作用与应用
BeanPostProcessor是Spring IOC容器给我们提供的一个扩展接口。,他的作用主要是如果我们需要在Spring 容器完成 Bean 的实例化、配置和其他的初始化前后添加一些自己的逻辑处理,我们就可以定义一个或者多个 BeanPostProcessor 接口的实现,然后注册到容器中。
接口声明如下:
public interface BeanPostProcessor {
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {return bean;}
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {return bean;}
}
方法说明:
- postProcessBeforeInitialization:该方法在bean初始化方法调用前被调用,也就是有@PostConstruct注解的方法。
- postProcessAfterInitialization:该方法在bean初始化方法调用后被调用,注意,如果bean有代理的话,那么该bean是被代理后的对象。
一、如何利用BeanPostProcessor
BeanPostProcessor被经常用在使用代理模式的框架设计中,比如spring中的事务,以及spring aop代理等。那么有时开发者需要自己去定义代理的方式实现某些功能,比如下面要介绍的用自定义注解做登录拦截。
自定义注解,实现访问有该注解的控制器下的所有接口,必须先登录。
1、简单定义一个注解
import java.lang.annotation.*;
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,ElementType.TYPE})
public @interface LoginRequired {
}
1、声明BeanPostProcessor实例
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.lang.reflect.Method;
/**
* @author: Jiajiajia
*/
@Component
public class LoginBeanPostProcessor implements BeanPostProcessor , Ordered {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
Class<?> beanClass = bean.getClass();
boolean hasLoginRequired = hasLoginRequired(beanClass);
if(hasLoginRequired){
// 对目标类进行代理
Enhancer eh = new Enhancer();
eh.setSuperclass(bean.getClass());
eh.setCallback(new Interceptor());
return eh.create();
}
return bean;
}
public boolean hasLoginRequired(Class<?> clazz){
LoginRequired annotation = clazz.getAnnotation(LoginRequired.class);
if(annotation != null){
return true;
}else{
if(clazz.getSuperclass() == Object.class || clazz.getSuperclass() == null){
return false;
}else{
return hasLoginRequired(clazz.getSuperclass());
}
}
}
@Override
public int getOrder() {
return 0;
}
}
/**
* *方法拦截器
*/
class Interceptor implements MethodInterceptor {
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
// 目标方法执行之前 判断是否登录
if(没有登录){
抛异常
}
Object o = proxy.invokeSuper(obj, args);
return o;
}
}
上面的代码只是一个简单的例子,还有很多的使用方法还需要看具体的业务,以及开发者们的设计能力。
猜你喜欢
blog
cglib代理常用接口和api
ASM,java基础
1101
、InvocationHandler InvocationHandler可以实现对接口的代理,类似与mybatis,代码中开发者只需要写一个接口和一个xml,mybatis会根据xml的描述信息,帮你生成对应的方法实现,参数的解析
blog
栈的应用-表达式求值
数据结构与算法
1704
表达式:ab+ab-*高级语言中采用自然语言的中缀表达式,但是计算机对中缀表达式的处理是非常困难的,而对后缀或前缀表达式则显得非常简单后缀表达式的特点: 1.在后缀表达式中,变量(操作数)出现的顺序与中
工具
2905
/dependency2.java代码调用SoapClientclient=SoapClient.create("http://cwzf.zzcsjr.edu.cn/xysf/OrderView.asmx")//设
spring/springmvc
1630
"spring在ioc容器中获取aop的受理对象",这句话是什么意思呢?有时候我们会在spring项目中对一下类进行代理,比如我们会用spring的aop和自定义注解对一些接口访问添加日志,再比如对
框架
5492
springmvc项目中,如一个项目的页面调用另一个项目的接口会产生跨域问题403。对于一个接口而言很好解决跨域问题,springmvc中只需要在接口上加一个注解。@CrossOrigin
ofc
系统调用
official
871
给应用程序(程序员/编程人员)使用的接口,可以理解为一种可供应用程序调用的特殊函数,应用程序可以发出系统调用请求来获得操作系统的服务。应用程序通过系统调用请求操作系统的服务。系统中的各种共享资源都由操作
框架
1963
springboot获取项目中所有对外提供的接口信息@ComponentpublicclassTestimplementsApplicationRunner
框架
1633
能手动去写这些逻辑。最终把它封装成一个可以方便直接转换成对象得工具类。首先明确我们得目的是什么现有一个excel表,如下图:现需要把excel表中的每一行都封装在一个java对象中,当然如果用poi的a
目录
没有一个冬天不可逾越,没有一个春天不会来临。最慢的步伐不是跬步,而是徘徊,最快的脚步不是冲刺,而是坚持。