SSM_003.Spring控制反转

一、简介

Spring框架是由于软件开发的复杂性而创建的。Spring使用的是基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅仅限于服务器端的开发。从简单性、可测试性和松耦合性角度而言,绝大部分Java应用都可以从Spring中受益。

目的:解决企业应用开发的复杂性
功能:使用基本的JavaBean代替EJB,并提供了更多的企业应用功能
范围:任何Java应用

Spring是一个轻量级控制反转(IoC)和面向切面(AOP)的容器框架。

    (1)ioc:控制反转,降低类之间的耦合性。创建类的对象时,不是通过new的方式、而是交给Spring配置创建对象。

    (2)aop:面向切面编程,扩展功能不是通过修改源代码实现。尤其是对数据库对应用,通过切面消除了以前复杂对try catch finally代码结构

Spring是一站式框架。

    (1)Spring在Javaee三层框架中,每一层都提供了不同的解决技术。

        -web层:SpringMVC

        -service层:Spring的ioc

        -dao层:Spring的jdbcTemplate

二、ioc

把对象的创建交给Spring进行管理

ioc操作分为:

    (1):ioc的配置文件方式

    (2):ioc的注解方式

ioc底层原理:

使用工厂模式降低耦合。

建一个工厂类,提供返回需新建的对象的静态方法。

ioc原理实现步骤:

    1.创建xml配置文件,配置要创建的对象类

    2.创建工厂类。

        2.1使用dom4j解析配置文件+反射(根据配置文件的的id值,得到id对应的class属性值)。

        2.2使用反射创建类的方法。

ioc入门案例:

(1)导入Spring框架中的相关jar包,这里只导入Spring的Core模块(Core模块是框架的核心类库)下的jar包(使用IoC的基本操作,并不需要导入Spring的所有jar包,只导入spring-beans、spring-core、spring-context、spring-expression这4个jar包),以及 支持日志输出的 commons-logging 和 log4j 的jar包; 

(2)创建一个普通的Java类,并在该类中创建方法,如下: 

  User.java

package ioc;

public class User {

	public void add(){
		System.out.println("add...");
	}

}

 

(3)创建Spring的配置文件,进行Bean的配置 
  Spring的核心配置文件名称和位置不是固定的。但官方件建议将该核心配置文件放在src目录下,且命名为 applicationContext.xml。 并且要引入schema约束,目录spring-framework-5.0.6.RELEASE\docs\spring-framework-reference\html5\core.html

 

  这里为了方便,将核心配置文件放在src目录下,并命名为 applicationContext.xml,内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    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">

    <bean 
    	id="user" class="ioc.User">
  	</bean>

</beans>

 

Bean标签的常用属性

(1)id属性:用于指定配置对象的名称,不能包含特殊符号。 
(2)class属性:创建对象所在类的全路径。 
(3)name属性:功能同id属性一致。但是在name属性值中可以包含特殊符号。 
(4)scope属性

  • singleton:默认值,单例 
    单例模式下,在程序下只有一个实例。非单态模式下,每次请求该Bean,都会生成一个新的对象。
  • prototype:多例
  • request:创建对象后将对象存放到request域
  • session:创建对象后将对象存放到session域
  • globalSession:创建对象后将对象存放到globalSession域

 

(4)编写测试类进行测试,通过配置文件创建类对象 

 

TestIoC.java

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

public class TestIoc {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//加载Spring配置文件,根据配置创建对象
		ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
		//得到配置创建的对象
		User user=(User) context.getBean("user");
		
		user.add();
	}

}

运行结果:

log4j:WARN No appenders could be found for logger (org.springframework.core.env.StandardEnvironment).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
add...

去掉前面的提示(转载自:https://www.cnblogs.com/jbelial/archive/2012/06/05/2536814.html)

 

在src下面新建file名为log4j.properties内容如下:

# Configure logging for testing: optionally with log file
log4j.rootLogger=WARN, stdout
# log4j.rootLogger=WARN, stdout, logfile

log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n

log4j.appender.logfile=org.apache.log4j.FileAppender
log4j.appender.logfile.File=target/spring.log
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=%d %p [%c] - %m%n

===============================
重新发布,OK,没有提示了。加入了这个配置文件后,再次运行程序上面的警告就会消失。尤其在进行Web 层开发的时候,只有加入了这个文件后才能看到Spring 后台完整的出错信息。

 

如果配置文件没有提示,eclipse→windows→preferences→xml catalog→add  找到schema/bean  把约束文件添加进去,key type改为Location

 

属性注入:使用有参构造器或set方法注入属性。

    通过有参构造器注入, student.java

package ioc;

/*使用有参构造函数注入属性
 * 配置文件:
 * <bean
  		id="student" class="ioc.Student">
  		<constructor-arg name="name" value="zz"></constructor-arg>
  	</bean>
 */
public class Student {
	private String name;
	public Student(String name){
		this.name=name;
	}
	@Override
	public String toString() {
		return "Student [name=" + name + "]";
	}
	
}

通过set方法注入,Teacher.java

package ioc;
/*使用set方法注入属性
 * <bean
  		id="teacher" class="ioc.Teacher">
  			<property name="name" value="Teacher wu"></property>
  		</bean>
 * */
public class Teacher {
	private String name;

	public void setName(String name) {
		this.name = name;
	}

	@Override
	public String toString() {
		return "Teacher [name=" + name + "]";
	}
	
}

TestIoc.java

Student st=(Student) context.getBean("student");
		System.out.println(st.toString());
		
		Teacher te=(Teacher) context.getBean("teacher");
		System.out.println(te.toString());

对象的注入:

 java三层架构

业务层(逻辑层、service层)

采用事务脚本模式。将一个业务中所有的操作封装成一个方法,同时保证方法中所有的数据库更新操作,即保证同时成功或同时失败。避免部分成功部分失败引起的数据混乱操作。

表现层(JSP)

采用MVC模式。 
M称为模型,也就是实体类。用于数据的封装和数据的传输。 
V为视图,也就是GUI组件,用于数据的展示。 
C为控制,也就是事件,用于流程的控制。

持久层(DAO)

采用DAO模式,建立实体类和数据库表映射(ORM映射)。也就是哪个类对应哪个表,哪个属性对应哪个列。持久层的目的就是,完成对象数据和关系数据的转换。

我们在DAO层进行数据库的操作,在Service层进行业务逻辑操作,那我在Service中需要有一个DAO实例

 

实现思想:

1、创建service类和dao类 
2、在service得到dao对象 
(以service中内嵌dao为例)

具体实现过程:

  • 1)在service中把dao作为类型属性
  • 2)生成dao类型属性的set方法
  • 3)配置文件中完成注册

UserDao.java

package ioc;

public class UserDao {
	public void add(){
	    System.out.println("dao");
	}
}

UserService.java

package ioc;
/*
 * <bean
  		id="userService" class="ioc.UserService">
  		 <!--  注入dao对象  name:service类中属性名称  ref属性:dao配置bean标签中的id值 -->
  		<property name="UserDao" ref="userDao"></property>
 	</bean>
 * */
public class UserService {
	private UserDao userDao;//定义dao类型属性
	public void setUserDao(UserDao userDao){
		this.userDao=userDao;
	}
	public void add(){
		System.out.println("service");
		//不使用Spring框架,直接创建UserDao对象
        //UserDao userDao =  new UserDao();
        //userDao.add();
		userDao.add();
	}
}

 

applicationContext.xml

 

<bean
  		id="userDao" class="ioc.UserDao">
 	</bean>
 	
 	<bean
  		id="userService" class="ioc.UserService">
  		 <!--  注入dao对象  name:service类中属性名称  ref属性:dao配置bean标签中的id值 -->
  		<property name="UserDao" ref="userDao"></property>
 	</bean>

TestIoc.java

        UserService userService = (UserService) context.getBean("userService");
	userService.add();  //验证是否可以得到UserService对象

数组注入&List集合注入&Map注入&Properties注入

User7.java

package ioc;

import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

public class User7 {
	    private String[] names;
	    private List<String> list;
	    private Map<String, String> map;
	    /*java中的properties文件是一种配置文件,
	     * 主要用于表达配置信息,文件类型为*.properties,格式为文本文件,
	     * 文件的内容是格式是"键=值"的格式,
	     * 在properties文件中,可以用"#"来作注释,
	     * properties文件在Java编程中用到的地方很多,操作很方便。*/
	    private Properties properties;

	    public void setNames(String[] names) {
	        this.names = names;
	    }

	    public void setList(List<String> list) {
	        this.list = list;
	    }

	    public void setMap(Map<String, String> map) {
	        this.map = map;
	    }

	    public void setProperties(Properties properties) {
	        this.properties = properties;
	    }
	    public void test() {
	        StringBuffer sb1 = new StringBuffer();
	        for (String name : names) {
	            sb1.append(name).append(",");
	        }
	        
	        StringBuffer sb2 = new StringBuffer();
	        for (String s : list) {
	            sb2.append(s).append(",");
	        }
	        StringBuffer sb3 = new StringBuffer();
	        
	        Set<String> keySet = map.keySet();
	        for (String s : keySet) {
	            sb3.append("key:" + s + ";value:" + map.get(s)).append(",");
	        }
	        
	        System.out.println(sb1.toString());
	        System.out.println(sb2.toString());
	        System.out.println(sb3.toString());
	        
	        System.out.println(properties.getProperty("username"));
	    }
}

applicationContext.xml

<bean id="user7" class="ioc.User7">
        <property name="names">
            <list>
                <value>张三</value>
                <value>李四</value>
                <value>王五</value>
            </list>
        </property>
        <property name="list">
            <list>
                <value>足球</value>
                <value>篮球</value>
                <value>乒乓球</value>
            </list>
        </property>

        <property name="map">
            <map>
                <entry key="username" value="张三"/>
                <entry key="password" value="123456"/>
            </map>
        </property>
        <property name="properties">
            <props>
                <prop key="username">赵六</prop>
            </props>
        </property>
    </bean>

TestIoc.java

 User7 user7=(User7)context.getBean("user7");
user7.test();

运行结果:

张三,李四,王五,
足球,篮球,乒乓球,
key:username;value:张三,key:password;value:123456,
赵六

IOC(控制反转)和DI(依赖注入)的关系:
(1)IOC: 控制反转,把对象创建交给spring进行配置
(2)DI: 依赖注入,向类里面的属性中设置值
(3)关系:依赖注入不能单独存在,需要在ioc基础之上完成操作

 

Spring的bean管理(注解)

 

参考文章:https://blog.csdn.net/m0_38021128/article/details/69372109

                https://blog.csdn.net/qq_15096707/article/details/72819930#spring¦ᄌᆳ￧レトioc₩モヘ¦ᄑワ

                https://blog.csdn.net/qq_25827845/article/details/53888749

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值