不想网站备案如何办,网络科技公司起名大全参考,如何做网站弹窗,涪陵网站建设公司最近在项目中出现了一个这种情况#xff1a;我一顿操作猛如虎的写了好几个设计模式#xff0c;然后在设计模式中的类中想将数据插入数据库#xff0c;因此调用Mapper持久层#xff0c;但是数据怎么都写不进去#xff0c;在我一顿操作猛如虎的查找下#xff0c;发现在普通…最近在项目中出现了一个这种情况我一顿操作猛如虎的写了好几个设计模式然后在设计模式中的类中想将数据插入数据库因此调用Mapper持久层但是数据怎么都写不进去在我一顿操作猛如虎的查找下发现在普通类中用Autowired注入的Bean是Null也就是说注入失败了瞎搞。
针对以上情况我做了三种解决方案经测试均可行解决方案如下
在设计模式中只操作数据最后还是将数据返回给Controller层再由Controller向下调用写入数据库简化设计模式然后将其注册为Service然后再Service中调用Mapper层通过Bean工具的方式在普通类中获取Bean然后将内容写入数据库。
经过测试三种情况均可行最终我选择了3。 文章目录 情况复现正文 | 获取一个Bean方式 1 | 通过实现ApplicationContextAwre方式获取Bean1.1 实现1.2 使用 方式 22.2 使用 方式 3 | 继承ApplicationObjectSupport的方式获取Bean3.1 实现3.2 测试 方式 4 | 继承WebApplicationObjectSupport4.2 测试 方式 5 | 通过WebApplicationContextUtils5.1 实现5.2 测试 致谢 - 以下代码均经过我的测试请放心使用 - 情况复现 抄作业可以跳转至正文 情况复现比较简单我们只需要一个Bean即可Bean代码如下
Bean代码
Component
public class TestComponent {public String say() {System.out.println(执行成功);return 执行成功;}}在以上代码中我们将TestComponent注册成为了一个Bean为了严禁我们还需要在Controller中调用一下这个类的方法测试一下该类是否真的被注入进去了但是为了文章不要太冗余这一块内容我省略掉结论是我测试过是可以在Controller中调用的。
通过普通类调用该Bean
实现思想我们写一个普通的类在Controller中new出该类的对象然后在该普通类中Autowired的方式注入该类并调用
验证方式首先我们会输出该Bean的地址如果注入成功的话我们会得到一长串字符其次如果成功的话页面与控制台均有输出 Controller层 只写个方法了类信息略
GetMapping(/com)
public String common() {CommonClazz clazz new CommonClazz();return clazz.say();
}普通类CommonClazz
public class CommonClazz {Autowiredprivate TestComponent component;public String say() {System.out.println(-----Bean:component);return component.say();}}以上代码中我们在Controller层new出来了CommonClazz的对象在CommonClazz中我们Autowired了测试Bean随后返回输出一气呵成逻辑严谨看似毫无问题一执行满是BUG执行结果如下 页面错误信息找不到该页面其实是有该路径只不过后台报错了
后台报错内容如下 可以看到首先我们对Bean的地址输出是null说明我们注入失败什么都没拿到因此用null来执行方法会报错也就可以理解了。 思考一下如果我这时候new一个Service层的实现类对象然后调用Mapper是否可以将数据写入数据库呢答案是否定的因为对于new出来的Service实现类来说它也是一个普通类而不是Bean但是Mapper层却是一个Bean这样又会出现现在的问题。 正文 | 获取一个Bean
方式 1 | 通过实现ApplicationContextAwre方式获取Bean
强烈推荐 这是一种比较推荐的写法我们不用再改写SpringBoot启动类且获取Bean的时候也不用传入Bean的名称只需要传入一个.class就可以了。 1.1 实现
SpringContextUtil代码如下
Component
public class SpringContextUtil implements ApplicationContextAware {private static ApplicationContext ac;Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {ac applicationContext;}public static T T getBean(ClassT clazz) {T bean ac.getBean(clazz);return bean;}}正如简介中所说这种方法不需要修改启动类我们只需要做这些就可以正常使用了。 1.2 使用
与方式一相比Controller与CommonClass类并没有发生太大的变化但是为了更好的阅读性我们还是全都展示出来。
Controller类依旧省略类信息只写方法
GetMapping(/com)
public void common() {CommonClazz clazz new CommonClazz();clazz.say();
}CommonClazz类
public class CommonClazz {public void say() {TestComponent bean SpringContextUtil.getBean(TestComponent.class);System.out.println(-----Bean:bean);bean.say();}}Bean类省略可以去前面复制
浏览器访问Controller层地址信息正常输出内容如下 可以看到Bean的地址被正确输出说明不是null也输出了Bean中方法的内容说明Bean被正常注入了。 方式 2
推荐 这种实现可以在任意类中获取一个Bean但是要修改SpringBoot启动类并且在获取Bean的时候要传入两个参数有点冗余个人觉得使用起来不如方式1当然也可以通过改写getBean()方法的方式只传入一个Bean。 ### 2.1 实现
首先我们要简单改造一下SpringBoot启动类变动如下
SpringBootApplication
public class JimTestApplication {public static void main(String[] args) {ConfigurableApplicationContext run SpringApplication.run(JimTestApplication.class, args);SpringContextUtil.setAc(run);}}其次我们创建一个SpringContextUtil工具类内容如下
public class SpringContextUtil {private static ApplicationContext ac;public static T T getBean(String beanName, ClassT clazz) {T bean ac.getBean(beanName, clazz);return bean;}public static void setAc(ApplicationContext applicationContext){ac applicationContext;}
}**大功告成**接下来只需要在普通类中调用该工具类中的方法就可以获得一个Bean了接下来我们测试一下、
测试思路与上面一样我们通过Controller new普通类对象然后在普通类对象中通过这个工具类获取一个Bean并且输出Bean的地址以及调用Bean的方法
为了方便测试所有的方法都不加返回值了直接输出 后面也是如此。 2.2 使用
Controller类new CommonClazz()依旧省略类信息直接写方法
GetMapping(/com)
public void common() {CommonClazz clazz new CommonClazz();clazz.say();
}CommonClazz类信息如下
public class CommonClazz {public void say() {// 使用如下TestComponent bean SpringContextUtil.getBean(testComponent,TestComponent.class);System.out.println(-----Bean:bean);bean.say();}}Bean(TestComponent)没有做多大的改动只是有返回值改成void了为了节省篇幅这里也省略不写了。
我们在浏览器调用Controller的地址之后控制台得到如下输出 结论Bean被正确注入 方式 3 | 继承ApplicationObjectSupport的方式获取Bean
不推荐 这是一种比较鸡肋的方法使用起来有很大的局限性它只能在Bean中使用。因为它本身也需要作为Bean被注入后才能生效。 3.1 实现
SpringContextUtil类内容如下
Service
public class SpringContextUtil extends ApplicationObjectSupport {public T T getBean(ClassT clazz) {T bean getApplicationContext().getBean(clazz);return bean;}}3.2 测试
老样子为了方便阅读我决定省略测试内容直接说测试结果。
在普通类中使用失败获取的测试Bean是一个null在Controller中直接将该类作为BeanAutowired进去因为Service注解就想到了获取Bean成功我也尝试了一些其他的办法在普通类中使用均失败了有好办法的话告诉我吧。 方式 4 | 继承WebApplicationObjectSupport
不推荐 与**[方式3]**一样它也只能在Bean中使用因此也很不推荐。 ### 4.1 实现
Service
public class SpringContextUtil extends WebApplicationObjectSupport {public T T getBean(ClassT clazz) {T bean getApplicationContext().getBean(clazz);return bean;}}4.2 测试
同[方式3]略。 方式 5 | 通过WebApplicationContextUtils
不推荐 适用于web项目的b/s结构。只适合获取web项目中。 补充该bean 定义对应于单个websocket 的生命周期。该作用域仅适用于WebApplicationContext环境。 5.1 实现
SpringContextUtil代码
public class SpringContextUtil {public static T T getBean(ServletContext request, String name, ClassT clazz){WebApplicationContext webApplicationContext WebApplicationContextUtils.getRequiredWebApplicationContext(request);// 或者WebApplicationContext webApplicationContext1 WebApplicationContextUtils.getWebApplicationContext(request);
// webApplicationContext1.getBean(name, clazz)T bean webApplicationContext.getBean(name, clazz);return bean;}}5.2 测试
首先第一个参数不能传递null,否则会报错暂时没有这种场景后面我就没测偷懒 致谢 感谢 华为云 | springboot获取bean的几种常用方式 对本博客的帮助