Spring之IOC详解

1.spring概述

它是为了解决企业应用开发的复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许使用者选择使用哪一个组件,同时为J2EE应用程序开发提供集成的框架。Spring使用基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅限于服务器端的开发。从简单性、可测试性和松耦合的角度而言,任何Java应用都可以从Spring中受益。Spring的核心是控制反转(IoC)和面向切面(AOP)。简单来说,Spring是一个分层的JavaSE/EEfull-stack(一站式)轻量级开源框架。

2.IOC概述


IOC即Inversion of Control,反应过来就是控制反转。啥是控制反转啊?控制反转指的就是将对象的创建权反转给(交给)了Spring,其作用是实现了程序的解耦合。也可这样解释:获取对象的方式变了,对象创建的控制权不是"使用者",而是"框架"或者"容器"。用更通俗的话来说,IoC就是指对象的创建,并不是在代码中用new操作new出来的,而是通过Spring进行配置创建的。

2.1Spring的IoC的底层实现原理

Spring的IoC的底层实现原理是工厂设计模式+反射+XML配置文件

首先创建接口

package com.wyy.biz;

import com.wyy.entity.User;

public interface userBiz {
	public void add();
	
}

接口实现类

package com.wyy.biz.impl;

import com.wyy.biz.userBiz;
import com.wyy.entity.User;

public class userBizimpl implements userBiz {
	@Override
	public void add() {
		System.out.println("---------------");
		
	}

}

方法调用

package com.wyy.text;

import com.wyy.biz.userBiz;
import com.wyy.biz.impl.userBizimpl;

public class text {
public static void main(String[] args) {
	userBiz user=new userBizimpl();
	user.add();
}
}

这时我们便可发现一个缺点:service层和dao层耦合度太高了,即接口和实现类有耦合(它俩之间的联系过于紧密),一旦切换底层实现类,那么就需要修改源代码,这真的不是一个好的程序设计,好的程序设计应当满足OCP原则(也即开闭原则),即在尽量不修改程序源代码的基础上对程序进行扩展。解决方法是使用工厂设计模式进行解耦合操作。所以,我们需要创建一个工厂类,在工厂类中提供一个方法,返回实现类的对象。

package com.wyy.factory;

import com.wyy.biz.userBiz;
import com.wyy.biz.impl.userBizimpl;

public class UserFactory {
	/**
	 * 提供返回实现类对象的方法
	 * @return
	 */
	public static userBiz getUserBiz() {
		return new userBizimpl();
	}
}

此时方法调用形式如下

package com.wyy.text;

import com.wyy.biz.userBiz;
import com.wyy.factory.UserFactory;

public class text {
public static void main(String[] args) {
	userBiz user=UserFactory.getUserBiz();
	user.add();
}
}

如若这样做,会发现又产生了一个缺点:现在接口和实现类之间是没有耦合了,但是service层和工厂类耦合了。如果真正想实现程序之间的解耦合,那么就需要使用到工厂设计模式+反射+XML配置文件了。所以,我们这里提供一个XML配置文件,并且该配置文件中有如下配置信息。

然后再来创建一个工厂类,在工厂类中提供一个返回实现类对象的方法,但并不是直接new实现类,而是使用SAX解析配置文件,根据标签bean中的id属性值得到对应的class属性值,使用反射创建实现类对象。

package com.wyy.factory;

import java.io.InputStream;
import java.util.List;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import com.wyy.biz.userBiz;
import com.wyy.biz.impl.userBizimpl;
import com.wyy.util.SAXutil;

public class UserFactory {
	
	public static Object getUser() throws Exception {
		//解析xml文件
		InputStream resourceAsStream = UserFactory.class.getResourceAsStream("spring-context.xml");
		SAXReader sax=new SAXReader();
		Document read = sax.read(resourceAsStream);
//		System.out.println(read.asXML());
		List selectNodes = read.selectNodes("/beans/bean");
		Object obj=null;
			for (Element element : selectNodes) {
				//的到对应的class全路径名
				String s = element.attributeValue("class");
				//反射获取对象
				Class forName = Class.forName(s);
				 obj = forName.newInstance();
			}
		return obj;
	}
}

 以上就是Spring的IoC的底层实现原理。

3.如何在spring当中定义和配置一个JavaBean

三种传参方式:

  • set传参
  • 构造传参
  • 自动装配(基本不用)

3.1set传参 

package com.wyy.action;

import java.util.List;

import com.wyy.biz.userBiz;
import com.wyy.biz.impl.userBizimpl;

public class userAction {
	//用户管理的dao层的接口
	private userBiz userp;
	//属性
	private int age;
	private String name;
	private List hobby;
	
	public userBiz getUserp() {
		return userp;
	}
	public void setUserp(userBiz userp) {
		this.userp = userp;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public List getHobby() {
		return hobby;
	}
	public void setHobby(List hobby) {
		this.hobby = hobby;
	}
	
	public void getred() {
		System.out.println(age);
		System.out.println(name);
		System.out.println(hobby);
	}
	
	public void add() {
		userp.add();
	}
}

spring配置文件



		
	
	
	
	
	
	
		
			sfz
			睡觉
		
	
	

package com.wyy.text;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.wyy.action.userAction;
import com.wyy.biz.userBiz;
import com.wyy.biz.impl.userBizimpl;
import com.wyy.factory.UserFactory;
/**
 *  Spring方式的调用
 * @author T440s
 *
 */
public class text {
public static void main(String[] args) throws Exception {
//	userBiz user=(userBizimpl)UserFactory.getUser();
//	user.add();
	ApplicationContext  applicationContext  = new ClassPathXmlApplicationContext("/spring-context.xml");
	userAction bean = (userAction) applicationContext.getBean("user");
	bean.getred();
	bean.add();
}
}

 结果输出

Spring之IOC详解_第1张图片

3.2构造传参

userAction添加有参构造器

package com.wyy.action;

import java.util.List;

import com.wyy.biz.userBiz;
import com.wyy.biz.impl.userBizimpl;

public class userAction {
	//用户管理的dao层的接口
	private userBiz userp;
	//属性
	private int age;
	private String name;
	private List hobby;
	
	public userBiz getUserp() {
		return userp;
	}
	public void setUserp(userBiz userp) {
		this.userp = userp;
	}
	public userAction() {
		// TODO Auto-generated constructor stub
	}
	public userAction(int age, String name, List hobby) {
		super();
		this.age = age;
		this.name = name;
		this.hobby = hobby;
	}
	public void getred() {
		System.out.println(age);
		System.out.println(name);
		System.out.println(hobby);
	}
	
	public void add() {
		userp.add();
	}
}

 修改spring配置文件



		
	
	
	
	
	
	
				
			sfz
			睡觉
		
	
	
	

Spring之IOC详解_第2张图片

4.spring与tomcat 整合

假设把对xml建模的业务代码放到请求中,那么在处理每一次浏览器请求时,都会建模一次,这无疑对性能的消耗太大。解决方案就是将xml建模业务代码放到监听器中,当服务开启时监听器只执行一次。

4.1监听器业务代码 

package com.wyy.listener;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpringListener implements ServletContextListener{
	/**
	 * 
	 */
	@Override
	public void contextInitialized(ServletContextEvent sce) {
		System.out.println("监听器执行.......");
		ApplicationContext  applicationContext  = new ClassPathXmlApplicationContext("/spring-context.xml");
		sce.getServletContext().setAttribute("spring", applicationContext);
	}
}

需要建模的xml文件也可以配置到web.xml中,使代码更加灵活。 

4.2web.xml配置监听器


  Archetype Created Web Application
  
  
  com.wyy.listener.SpringListener
  



4.2测试

package com.wyy.action;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.context.ApplicationContext;
@WebServlet("/text")
public class textAction extends HttpServlet{

	@Override
	protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		ApplicationContext attribute = (ApplicationContext) req.getServletContext().getAttribute("spring");
		userAction bean = (userAction) attribute.getBean("user");
		bean.add();
		bean.getred();
	}
}

Spring之IOC详解_第3张图片

 

 

你可能感兴趣的:(spring,java,后端)