一、简介
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