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