当前位置: 首页 > news >正文

宠物网站建设费用门户网站模版

宠物网站建设费用,门户网站模版,龙岗网,建筑师网站在日常项目开发中#xff0c;单例模式可以说是最常用到的设计模式#xff0c;项目也常常在单例模式中需要使用 Service 逻辑层的方法来实现某些功能。通常可能会使用 Resource 或者 Autowired 来自动注入实例#xff0c;然而这种方法在单例模式中却会出现 NullPointExceptio…在日常项目开发中单例模式可以说是最常用到的设计模式项目也常常在单例模式中需要使用 Service 逻辑层的方法来实现某些功能。通常可能会使用 Resource 或者 Autowired 来自动注入实例然而这种方法在单例模式中却会出现 NullPointException 的问题。那么本篇就此问题做一下研究。 演示代码地址 问题初探 一般我们的项目是分层开发的最经典的可能就是下面这种结构 ├── UserDao -- DAO 层负责和数据源交互获取数据。 ├── UserService -- 服务逻辑层负责业务逻辑实现。 └── UserController -- 控制层负责提供与外界交互的接口。此时需要一个单例对象此对象需要 UserService 来提供用户服务。代码如下 Slf4j public class UserSingleton {private static volatile UserSingleton INSTANCE;Resourceprivate UserService userService;public static UserSingleton getInstance() {if (null INSTANCE) {synchronized (UserSingleton.class) {if (null INSTANCE) {INSTANCE new UserSingleton();}}}return INSTANCE;}public String getUser() {if (null userService) {log.debug(UserSingleton userService is null);return UserSingleton Exception: userService is null;}return userService.getUser();} }然后创建一个 UserController 来调用 UserSingleton.getUser() 方法看看返回数据是什么。 RestController public class UserController {Resourceprivate UserService userService;/*** 正常方式在 Controller 自动注入 Service。** return user info*/GetMapping(/user)public String getUser(){return userService.getUser();}/*** 使用单例对象中自动注入的 UserService 的方法** return UserSingleton Exception: userService is null*/GetMapping(/user/singleton/ioc)public String getUserFromSingletonForIoc(){return UserSingleton.getInstance().getUser();} }user-info.png 可以看到在 UserController 中自动注入 UserService 是可以正常获取到数据的。 UserSingleton-exception.png 但是如果使用在单例模式中使用自动注入的话UserService 是一个空的对象。 所以使用 Resource 或者 Autowired 注解的方式在单例中获取 UserService 的对象实例是不行的。如果没有做空值判断会报 NullPointException 异常。 问题产生原因 之所以在单例模式中无法使用自动依赖注入是因为单例对象使用 static 标记INSTANCE 是一个静态对象而静态对象的加载是要优先于 Spring 容器的。所以在这里无法使用自动依赖注入。 问题解决方法 解决这种问题其实也很简单只要不使用自动依赖注入就好了在 new UserSingleton() 初始化对象的时候手动实例化 UserService 就可以了嘛。但是这种方法可能会有一个坑或者说只能在某些情况下可以实现。先看代码 Slf4j public class UserSingleton {private static volatile UserSingleton INSTANCE;Resourceprivate UserService userService;// 为了和上面自动依赖注入的对象做区分。// 这里加上 ForNew 的后缀代表这是通过 new Object()创建出来的private UserService userServiceForNew;private UserSingleton() {userServiceForNew new UserServiceImpl();}public static UserSingleton getInstance() {if (null INSTANCE) {synchronized (UserSingleton.class) {if (null INSTANCE) {INSTANCE new UserSingleton();}}}return INSTANCE;}public String getUser() {if (null userService) {log.debug(UserSingleton userService is null);return UserSingleton Exception: userService is null;}return userService.getUser();}public String getUserForNew() {if (null userServiceForNew) {log.debug(UserSingleton userService is null);return UserSingleton Exception: userService is null;}return userServiceForNew.getUser();} }下面是 UserService 的代码。 public interface UserService {/*** 获取用户信息** return link{String}*/String getUser();/*** 获取用户信息从 DAO 层获取数据** return*/String getUserForDao(); }Slf4j Service public class UserServiceImpl implements UserService {Resourceprivate UserDao userDao;Overridepublic String getUser() {return user info;}Overridepublic String getUserForDao(){if(null userDao){log.debug(UserServiceImpl Exception: userDao is null);return UserServiceImpl Exception: userDao is null;}return userDao.select();} }创建一个 UserController 调用单例中的方法做下验证。 RestController public class UserController {Resourceprivate UserService userService;// 正常方式在 Controller 自动注入 Service。GetMapping(/user)public String getUser(){return userService.getUser();}// 使用单例对象中自动注入的 UserService 的方法// 返回值是: UserSingleton Exception: userService is nullGetMapping(/user/singleton/ioc)public String getUserFromSingletonForIoc(){return UserSingleton.getInstance().getUser();}// 使用单例对象中手动实例化的 UserService 的方法// 返回值是: user infoGetMapping(/user/singleton/new)public String getUserFromSingletonForNew(){return UserSingleton.getInstance().getUserForNew();}// 使用单例对象中手动实例化的 UserService 的方法在 UserService 中通过 DAO 获取数据// 返回值是: UserServiceImpl Exception: userDao is nullGetMapping(/user/singleton/new/dao)public String getUserFromSingletonForNewFromDao(){return UserSingleton.getInstance().getUserForNewFromDao();} }通过上面的代码可以发现通过手动实例化的方式是可以一定程度上解决问题的。但是当 UserService 中也使用自动依赖注入比如 Resource private UserDao userDao;并且单例中使用的方法有用到 userDao 就会发现 userDao 是个空的对象。 也就是说虽然在单例对象中手动实例化了 UserService 但 UserService 中的 UserDao 却无法自动注入。其原因其实与单例中无法自动注入 UserService 是一样的。所以说这种方法只能一定程度上解决问题。 最终解决方案 我们可以创建一个工具类实现 ApplicationContextAware 接口用来获取 ApplicationContext 上下文对象然后通过 ApplicationContext.getBean() 来动态的获取实例。代码如下 import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.stereotype.Component;/*** Spring 工具类用来动态获取 bean** author James* date 2020/4/28*/ Component public class SpringContextUtils implements ApplicationContextAware {private static ApplicationContext applicationContext;Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {SpringContextUtils.applicationContext applicationContext;}/*** 获取 ApplicationContext** return*/public static ApplicationContext getApplicationContext() {return applicationContext;}public static Object getBean(String name) {return applicationContext.getBean(name);}public static T T getBean(ClassT clazz) {return applicationContext.getBean(clazz);}public static T T getBean(String name, ClassT clazz) {return applicationContext.getBean(name, clazz);} }然后改造下我们的单例对象。 Slf4j public class UserSingleton {private static volatile UserSingleton INSTANCE;// 加上 ForTool 后缀来和之前两种方式创建的对象作区分。private UserService userServiceForTool;private UserSingleton() {userServiceForTool SpringContextUtils.getBean(UserService.class);}public static UserSingleton getInstance() {if (null INSTANCE) {synchronized (UserSingleton.class) {if (null INSTANCE) {INSTANCE new UserSingleton();}}}return INSTANCE;}/*** 使用 SpringContextUtils 获取的 UserService 对象并从 UserDao 中获取数据* return*/public String getUserForToolFromDao() {if (null userServiceForTool) {log.debug(UserSingleton userService is null);return UserSingleton Exception: userService is null;}return userServiceForTool.getUserForDao();} }在 UserController 中进行测试看一下结果。 RestController public class UserController {/*** 使用 SpringContextUtils 获取的的 UserService 的方法在 UserService 中通过 DAO 获取数据** return user info for dao*/GetMapping(/user/singleton/tool/dao)public String getUserFromSingletonForToolFromDao(){return UserSingleton.getInstance().getUserForToolFromDao();} }访问接口返回结果是user info for dao验证通过。
http://www.zqtcl.cn/news/674778/

相关文章:

  • 网站建设跟网站结构如何提高网站排名的方法
  • 网站模板 缓存商标网上开店创业计划书
  • 沧州网站建设微艾薇怎样给企业做网站
  • 如何做淘宝客的网站个人网站设计与制作代码
  • 信用门户网站建设观摩惠州专业做网站
  • wordpress打开网站前广告佛山百度推广seo服务
  • 松北建设局网站vps 用ip可以访问网站么
  • 网站图片内容免费开源crm
  • wordpress调用分类栏目wordpress文章优化
  • 建站公司上海企业官网模板下载
  • 网站建设推广话术wordpress 不显示缩略图
  • 企业电子商务网站建设和一般百拓公司做网站怎么样
  • 吉林网站建设司上海什么做网站的公司比较好
  • 吉安市建设规划局网站jsp wordpress
  • 建设银行贵金属网站微信小程序注册后怎么使用
  • 如何做律师网站河南建网站 优帮云
  • 云阳如何做网站网站建设旅游
  • 推荐一个简单的网站制作单位网站服务的建设及维护
  • tp5网站文档归档怎么做网站 信用卡支付接口
  • phpcms 企业网站网站建设中单页代码
  • 坑梓网站建设方案网络编程技术及应用
  • 电子商务网站建设 价格新媒体运营需要具备哪些能力
  • 做生存分析的网站电商网站运营建设的目标
  • 佛山 做网站邮箱官方网站注册
  • 生成flash的网站源码表白二维码制作网站
  • 定做专业营销型网站网站开发应用
  • 万盛建设局官方网站如何用群晖nas做网站
  • 建设装饰网站郑州惠济区建设局网站
  • 网站做标题有用吗网站优化多少钱
  • 婚庆设备租赁网站源码如何进行网站的建设和维护