2.3.依赖注入
2.3.1.Set注入(重点)
userAction.java
public class UserAction { private UserService userService; private String name; private String[] books; private List<String> hobbys; private Map<String,String> card; private Set<String> games; public Map<String, String> getCard() { return card; } public void setCard(Map<String, String> card) { this.card = card; } public Set<String> getGames() { return games; } public void setGames(Set<String> games) { this.games = games; } public String[] getBooks() { return books; } public void setBooks(String[] books) { this.books = books; } public List<String> getHobbys() { return hobbys; } public void setHobbys(List<String> hobbys) { this.hobbys = hobbys; } public String getName() { return name; } public void setName(String name) { this.name = name; } public UserService getUserService() { return userService; } public void setUserService(UserService userService) { this.userService = userService; } public String Update(){ userService.update(); System.out.println("名字:"+name); System.out.println("书籍:"); for (String book:books){ System.out.print("<<"+book+">>\t\n"); } System.out.println("爱好:"+hobbys); System.out.println("card:"+card); System.out.println("games:"+games); return "list"; } }
GoodsAction.java
public class GoodsAction { private UserService userService; public UserService getUserService() { return userService; } public void setUserService(UserService userService) { this.userService = userService; } public String Update(){ userService.update(); return "list"; } }
Test测试类
public class UserTest { public static void main(String[] args) { //加载spring核心配置文件(建模)获取spring的上下文对象 //上下文对象中可以获取任何Javabean对象 ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("/Spring-Context.xml"); //用户 UserAction useraction = (UserAction) context.getBean("userAction"); useraction.Update(); System.out.println(" ==============================="); //商品 GoodsAction goodsAction= (GoodsAction) context.getBean("goodsAction"); goodsAction.Update(); }
1.Bean注入
这里的值是一个引用,ref
<bean class="com.csdn.xw.web.UserAction" id="userAction"> <property name="userService" ref="serviceImpl2"></property> <property name="name" value="小明"></property> </bean> <bean class="com.csdn.xw.service.impl.UserServiceImpl2" id="serviceImpl2"></bean>
2.数组注入
<property name="books" > <array> <value>西游记</value> <value>红楼梦</value> <value>水浒传</value> <value>三国演义</value> </array> </property>
3.List注入
<property name="hobbys"> <list> <value>唱</value> <value>跳</value> <value>RAP</value> </list> </property>
4.Map注入
<property name="card"> <map> <entry key="JAVA" value="100"></entry> <entry key="Python" value="100"></entry> </map> </property>
5.Set注入
<property name="games"> <set> <value>电脑</value> <value>鼠标</value> </set> </property>
测试结果:
2.3.2.构造注入
无参构造创建对象
userAction.java
public class UserAction { public UserAction() { System.out.println("user创建了"); } }
spring-context.xml
<bean class="com.csdn.xw.web.UserAction" id="UserAction"></bean>
测试结果:
有参构造创建对象
userAction.java
public class UserAction { private String name; private String[] books; private List<String> hobbys; private Map<String,String> card; private Set<String> games; //有参构造器 public UserAction(String name, String[] books, List<String> hobbys, Map<String, String> card, Set<String> games) { this.name = name; this.books = books; this.hobbys = hobbys; this.card = card; this.games = games; } /测试有无注入 public void pros(){ System.out.println("名字:"+name); System.out.println("书籍:"); for (String book:books){ System.out.print("<<"+book+">>\t\n"); } System.out.println("爱好:"+hobbys); System.out.println("card:"+card); System.out.println("games:"+games); } }
spring-context.xml
<bean class="com.csdn.xw.web.UserAction" id="userAction"> <property name="userService" ref="serviceImpl2"></property> <constructor-arg name="name" value="张三"></constructor-arg> <constructor-arg name="books"> <array> <value>大话数据结构</value> <value>大话设计模式</value> </array> </constructor-arg> <constructor-arg name="hobbys"> <list> <value>沐浴</value> <value>足疗</value> <value>按摩</value> </list> </constructor-arg> <constructor-arg name="card"> <map> <entry key="csdn" value="nb"></entry> </map> </constructor-arg> <constructor-arg name="games"> <set> <value>Java方文山</value> </set> </constructor-arg> </bean>
测试结果:
2.4.自动装配
byName(按名称自动装配)
由于在手动配置xml过程中,常常发生字母缺漏和大小写等错误,而无法对其进行检查,使得开发效率降低。采用自动装配将避免这些错误,并且使配置简单化。
测试:
1、修改bean配置,增加一个属性 autowire=“byName”
<bean class="com.csdn.xw.web.GoodsAction" id="goodsActiona" autowire="byName"> <property name="userService" ref="serviceImpl1"></property> </bean>
<beans xmlns="http://www.springframework.org/schema/beans" default-autowire="byName" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
2、再次测试,结果依旧成功输出!
3、我们将 GoodsAction的bean id修改为 goodsACtion
4、再次测试, 执行时报空指针java.lang.NullPointerException。因为按byName规则找不对应set方法,真正的setgoodsAction就没执行,对象就没有初始化,所以调用时就会报空指针错误。
小结:
当一个bean节点带有 autowire byName的属性时
或是beans节点带有 default-autowire="byName"。
- 将查找其类中所有的set方法名,例如setCat,获得将set去掉并且首字母小写的字符串,即cat。
- 去spring容器中寻找是否有此字符串名称id的对象。
- 如果有,就取出注入;如果没有,就报空指针异常。
byType (按类型自动装配)
使用autowire byType首先需要保证:同一类型的对象,在spring容器中唯一。如果不唯一,会报不唯一的异常。
NoUniqueBeanDefinitionException
测试:
1、将user的bean配置修改一下 : autowire=“byType”
2、测试,正常输出
3、在注册一个goodsAction的bean对象!
<bean class="com.csdn.xw.web.GoodsAction" id="goodsAction" autowire="byType"> </bean> <bean class="com.csdn.xw.web.UserAction" id="userAction" autowire="byType"> <property name="userService" ref="serviceImpl2"></property> </bean> <bean class="com.csdn.xw.service.impl.UserServiceImpl2" id="serviceImpl2"></bean> <bean class="com.csdn.xw.service.impl.UserServiceImpl1" id="serviceImpl1"></bean>
4、测试,报错:NoUniqueBeanDefinitionException
5、在这个配置中,我们定义了两个UserService的实现类 UserServiceImpl1和 UserServiceImpl2,并且将UserAction的autowire属性设置为byType,表示使用byType进行自动装配。
现在,如果我们运行这个程序,将会抛出一个异常,提示存在多个匹配的 bean,无法确定要注入哪个 bean。这是因为 UserAction类依赖于UserService接口,而容器中存在两个与 UserService接口匹配的 bean,即 UserServiceImpl1和 UserServiceImpl2,导致无法确定要注入哪个 bean。
这就是按照类型自动装配!
2.5.spring与web容器的整合
每一次的请求都需要进行建模,十分消耗新能,希望建模一次,然后每次的请求都可以拿到spring的上下文。使用监听器将spring上下文放入tomcat上下文中。
SpringLoadlistener.java
@WebListener public class SpringLoadlistener implements ServletContextListener { public void contextInitialized(ServletContextEvent sce) { System.out.println("初始化将Spring的上下文放入tomcat"); //将Spring的上下文放入tomcat ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("/Spring-Context.xml"); //获取tomcat上下文 ServletContext servletContext = sce.getServletContext(); servletContext.setAttribute("springcontext",context); } }
UserServlet.java
@WebServlet("/userlist") public class UserServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doPost(req,resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //处理请求的时候获取spring上下文 ClassPathXmlApplicationContext springcontext = (ClassPathXmlApplicationContext) req.getServletContext().getAttribute("springcontext"); UserAction useraction = (UserAction) springcontext.getBean("userAction"); System.out.println(useraction); useraction.Update(); } }
测试结果:
到这里我的分享就结束了,欢迎到评论区探讨交流!!
如果觉得有用的话还请点个赞吧 ♥ ♥