如何不通过依赖注入获取spring环境中的Bean

如何不通过依赖注入获取spring环境中的Bean,第1张

1、web容器启动,开始扫描所有被指定的spring配置文件。 2、根据配置文件,实例化所有的bean对象,以java语法创建。 3、加载spring配置文件配置的对象依赖关系,将有依赖关系的bean注入到相应的对象中。 你这里报错是因为,datasource对象还没有

背景:

SpringBoot日常开发中不需要接触原生>

你要用jsp调用spring的方法,应该是使用springMVC了 spring最简单的是用注解, 方法中你可以 @RequestMapping(value = "/demo") public class Demo{ @RequestMapping(value = "/aaaaction") public String aaa(){ return null; } } jsp调用的时

Spring的模块化是很强的 各个功能模块都是独立的 我们可以选择的使用 这一章先从Spring的IoC开始 所谓IoC就是一个用XML来定义生成对象的模式 我们看看如果来使用的

数据模型

如下图所示有三个类 Human(人类)是接口 Chinese(中国人)是一个子类 American(美国人)是另外一个子类

源代码如下

package chengang spring;public interface Human {void eat();void walk();}

package chengang spring;public class Chinese implements Human {/ (非 Javadoc) @see chengang spring Human#eat()/public void eat() {System out println( 中国人对吃很有一套 );}

/ (非 Javadoc) @see chengang spring Human#walk()/public void walk() {System out println( 中国人行如飞 );}}

package chengang spring;public class American implements Human {/ (非 Javadoc) @see chengang spring Human#eat()/public void eat() {System out println( 美国人主要以面包为主 );}

/ (非 Javadoc) @see chengang spring Human#walk()/public void walk() {System out println( 美国人以车代步 有四肢退化的趋势 );}}

对以上对象采用工厂模式的用法如下

创建一个工厂类Factory 如下 这个工厂类里定义了两个字符串常量 所标识不同的人种 getHuman方法根据传入参数的字串 来判断要生成什么样的人种

package chengang spring;public class Factory {public final static String CHINESE = Chinese ;public final static String AMERICAN = American ;

public Human getHuman(String ethnic) {if (ethnic equals(CHINESE))return new Chinese();else if (ethnic equals(AMERICAN))return new American();elsethrow new IllegalArgumentException( 参数(人种)错误 );}}

下面是一个测试的程序 使用工厂方法来得到了不同的 人种对象 并执行相应的方法

package chengang spring;public class ClientTest {public static void main(String[] args) {Human human = null;human = new Factory() getHuman(Factory CHINESE);human eat();human walk();human = new Factory() getHuman(Factory AMERICAN);human eat();human walk();}}

控制台的打印结果如下

采用Spring的IoC的用法如下

在项目根目录下创建一个bean xml文件

<xml version= encoding= UTF ><!DOCTYPE beans PUBLIC //SPRING//DTD BEAN//EN beans dtd ><beans><bean id= Chinese class= chengang spring Chinese /><bean id= American class= chengang spring American /></beans>

bean xml的位置如下图 注意不要看花眼把它看成是lib目录下的了 它是在myspring目录下的

修改ClientTest程序如下

package chengang spring;import ntext ApplicationContext;import ntext support FileSystemXmlApplicationContext;public class ClientTest {public final static String CHINESE = Chinese ;public final static String AMERICAN = American ;

public static void main(String[] args) {// Human human = null;// human = new Factory() getHuman(Factory CHINESE);// human eat();// human walk();// human = new Factory() getHuman(Factory AMERICAN);// human eat();// human walk();

ApplicationContext ctx = new FileSystemXmlApplicationContext( bean xml );Human human = null;human = (Human) ctx getBean(CHINESE);human eat();human walk();human = (Human) ctx getBean(AMERICAN);human eat();human walk();}}

从这个程序可以看到 ctx就相当于原来的Factory工厂 原来的Factory就可以删除掉了 然后又把Factory里的两个常量移到了ClientTest类里 整个程序结构基本一样

再回头看原来的bean xml文件的这一句

<bean id= Chinese class= chengang spring Chinese />

id就是ctx getBean的参数值 一个字符串 class就是一个类(包名+类名) 然后在ClientTest类里获得Chinese对象就是这么一句

human = (Human) ctx getBean(CHINESE)

因为getBean方法返回的是Object类型 所以前面要加一个类型转换

总结

( )也许有人说 IoC和工厂模式不是一样的作用吗 用IoC好象还麻烦一点

举个例子 如果用户需求发生变化 要把Chinese类修改一下 那么前一种工厂模式 就要更改Factory类的方法 并且重新编译布署 而IoC只需要将class属性改变一下 并且由于IoC利用了Java反射机制 这些对象是动态生成的 这时我们就可以热插拨Chinese对象(不必把原程序停止下来重新编译布署)

( )也许有人说 即然IoC这么好 那么我把系统所有对象都用IoC方式来生成

注意 IoC的灵活性是有代价的 设置步骤麻烦 生成对象的方式不直观 反射比正常生成对象在效率上慢一点 因此使用IoC要看有没有必要 我认为比较通用的判断方式是 用到工厂模式的地方都可以考虑用IoC模式

( )在上面的IoC的方式里 还有一些可以变化的地方 比如 bean xml不一定要放在项目录下 也可以放在其他地方 比如 chengang spring包里 不过在使用时也要变化一下 如下所示

new FileSystemXmlApplicationContext( src/cn//chengang/spring/bean xml )

另外 bean xml也可以改成其他名字 这样我们在系统中就可以分门别类的设置不同的bean xml

( )关于IoC的低侵入性

什么是低侵入性?如果你用过Struts或EJB就会发现 要继承一些接口或类 才能利用它们的框架开发 这样 系统就被绑定在Struts EJB上了 对系统的可移植性产生不利的影响 如果代码中很少涉及某一个框架的代码 那么这个框架就可以称做是一个低侵入性的框架

Spring的侵入性很低 Humen java Chinese java等几个类都不必继承什么接口或类 但在ClientTest里还是有一些Spring的影子 FileSystemXmlApplicationContext类和ctx getBean方式等

现在 低侵入性似乎也成了判定一个框架的实现技术好坏的标准之一

( )关于bean xml的用法

bean xml的用法还有很多 其中内容是相当丰富的 假设Chinese类里有一个humenName属性(姓名) 那么原的bean xml修改如下 此后生成Chinese对象时 陈刚 这个值将自动设置到Chinese类的humenName属性中 而且由于singleton为true这时生成Chinese对象将采用单例模式 系统仅存在一个Chinese对象实例

<xml version= encoding= UTF ><!DOCTYPE beans PUBLIC //SPRING//DTD BEAN//EN beans dtd ><beans><bean id= Chinese class= chengang spring Chinese singleton= true ><property name= humenName ><value>陈刚</value></property></bean><bean id= American class= chengang spring American /></beans>

lishixinzhi/Article/program/Java/ky/201311/28795

<bean id="springBean" scope="prototype" class=""<property name="name" value="chen"/</bean<bean id="myAction" scope="prototype" class=""<property name="springBean" ref="springBean"/</bean如果是j2ee应用,启动web应用时将会自动加载ApplicationContext实例(Spring容器负责创建Bean实例)一旦struts2的myAction实例化,其中的SpringBean也会被自动注入进来,从而达到使用SpringBean的目的。[问题]但是仍有需要通过代码来调用SpringBean的情况:1)对于不是由spring创建管理的类,如在java 代码中直接使用new去创建一个对象,并且想在这个对象中使用SpringBean;因为这个对象并不是由Spring容器创建管理的类,所以即使它有setter方法,容器的springBean也不会被注入。2)动态更改springBean中的属性值,如在代码运行时,name值需要发生变动;3)对于一个独立的应用程序[解决]定义一个非Spring容器创建管理的类public class NonSpringClass implements ServletContextAware {private SpringBean springBean;//如果 testGetBean不是被Spring容器创建管理,即使它有setter方法,容器的springBean也不会被注入。public void setSpringBean(SpringBean springBean){thisspringBean=springBean;}//利用ApplicationContext 从spring容器中获得springBean;//Spring有两个核心接口BeanFactory和ApplicationContext,其中ApplicationContext是BeanFactory的子接口,//它们代表了Spring容器,Spring容器是产生Bean的工厂,用于管理容器中的Bean。

spring在普通类中注入bean实例 或注入静态变量的bean Spring的注入有一个问题就是普通类没有办法获得Bean文件中的bean实例。这就是如果是在Web的Servlet环境中可以通过WebApplicationContextUtils,如果是普通类就不好处理了。

以上就是关于如何不通过依赖注入获取spring环境中的Bean全部的内容,包括:如何不通过依赖注入获取spring环境中的Bean、[Kotlin]SpringBoot 获取原生HTTP Request内容实例化model、如何在jsp页面上直接调用spring产生的实例等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/9475034.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-28
下一篇 2023-04-28

发表评论

登录后才能评论

评论列表(0条)

保存