继承bean并重写方法逻辑以替换原有实现

前言

在企业产品化项目中,各个业务处理一般都有标准(通用)实现逻辑,以应对该产品(业务)面对的常见通用型需求。而如果产品下发给某个客户,且该客户要求某个业务逻辑需要做部分微小的个性化处理时,通常有以下几种处理方式:

其一,客户化的业务实现交给非产品模块,即交给个性化模块处理特殊业务,接口调用时同步改成调用该个性化接口,对产品层无影响,但另一方面对于较为复杂、关联处理较多的业务逻辑,显然改动点就大了;

其二,在产品代码中通过增加配置的方式,来处理该客户的个性逻辑,配置不启用也不会影响现有产品主逻辑,但是长此以往把各个客户的特殊处理都杂糅进来后,产品的代码将会变得十分臃肿和难以维护;

其三,如果产品代码在设计时预留了扩展的接口,则也只需要在个性化模块中做扩展实现即可,也不影响产品代码,但通常客户的需求是难以猜测的,具体怎么留有扩展也十分考验产品开发团队的业务和技术水平;

本文针对此问题,结合实际场景,分享一种通过继承原有实现类的bean方式,达到重写其原有方法,又不影响原先bean之间的依赖和调用关系。

定义注解OverrideBean

自定义重写bean注解,用于标注该bean是重写原来实现的类的bean(替代产品化实现bean

package mine.code.config.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 自定义重写bean注解
 *
 * @author BlueDriver
 * @email cpwu@foxmail.com
 * @date 2022/6/27 20:01
 * -----------------------------------------
 * Gitee: https://gitee.com/BlueDriver
 * Github: https://github.com/BlueDriver
 * -----------------------------------------
 */
@Target({
   ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface OverrideBean {
   

}

定义OverrideBeanDefinitionRegistryPostProcessor

用于将重写的bean替换其原先的bean(个性化实现bean替换产品实现bean),具体实现原理可结合注释和下文示例理解,建议配合源码食用(源码链接见文章末尾)

package mine.code.config.processor;

import mine.code.config.annotation.OverrideBean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.context.EnvironmentAware;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
抱歉,我之前的回答有误。在SSM + Shiro框架中,你可以继承`FormAuthenticationFilter`,并重写`onAccessDenied()`方法实现免登录功能。以下是修改后的示例代码: ```java public class CustomAuthenticationFilter extends FormAuthenticationFilter { @Override protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception { HttpServletRequest httpServletRequest = (HttpServletRequest) request; HttpServletResponse httpServletResponse = (HttpServletResponse) response; // 从Cookie中获取sessionId String sessionId = null; Cookie[] cookies = httpServletRequest.getCookies(); if (cookies != null) { for (Cookie cookie : cookies) { if ("sessionId".equals(cookie.getName())) { sessionId = cookie.getValue(); break; } } } // 从Redis中获取账号密码 Jedis jedis = new Jedis("redis_host", redis_port); String password = jedis.get(sessionId); // 调用Shiro的登录方法进行认证 UsernamePasswordToken token = new UsernamePasswordToken(sessionId, password); Subject subject = SecurityUtils.getSubject(); try { subject.login(token); return true; // 认证成功,继续访问原请求页面 } catch (AuthenticationException e) { return false; // 认证失败,重定向到登录页面 } } } ``` 然后,在Shiro配置文件中将自定义过滤器添加到过滤器链中,如下所示: ```xml <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <!-- ...其他配置... --> <property name="filters"> <map> <!-- ...其他过滤器配置... --> <entry key="authc"> <bean class="com.example.CustomAuthenticationFilter"> <!-- 设置登录页的URL --> <property name="loginUrl" value="/login"/> </bean> </entry> <entry key="user"> <bean class="org.apache.shiro.web.filter.authc.UserFilter"/> </entry> </map> </property> <property name="filterChainDefinitions"> <value> /login = anon /logout = logout /** = user </value> </property> </bean> ``` 通过以上步骤,在拦截器中重写`onAccessDenied()`方法实现从Cookie中获取sessionId并从Redis中获取账号密码进行Shiro认证。如果认证成功,用户将继续访问原请求页面,否则将重定向到登录页面。 请注意,在实际生产环境中,你需要根据具体情况对Cookie和Redis进行适当的安全性加固和保护。同时,以上代码仅为示例,你可以根据实际需求进行适当调整和扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值