Spring笔记
Posted chn.tiancx
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring笔记相关的知识,希望对你有一定的参考价值。
文章目录
说明下【本文是在网上听课做的笔记,代码是自己敲的,有些文字是复制的老师发的】
Spring
Spring框架介绍
Spring是一个轻量级的IoC和AOP的框架
IoC
控制反转
AOP
面向切面编程
Spring的功能
优点:
1)方便解耦,简化开发
Spring 就是一个大工厂,可以将所有对象的创建和依赖关系的维护交给 Spring 管理。
2)方便集成各种优秀框架
Spring 不排斥各种优秀的开源框架,其内部提供了对各种优秀框架(如 Struts2、Hibernate、MyBatis
等)的直接支持。
3)降低 Java EE API 的使用难度
Spring 对 Java EE 开发中非常难用的一些 API(JDBC、JavaMail、远程调用等)都提供了封装,使这些
API 应用的难度大大降低。
4)方便程序的测试
Spring 支持 JUnit4,可以通过注解方便地测试 Spring 程序。
5)AOP 编程的支持
Spring 提供面向切面编程,可以方便地实现对程序进行权限拦截和运行监控等功能。
6)声明式事务的支持
只需要通过配置就可以完成对事务的管理,而无须手动编程。
接口和Spring 是完美搭配
以前
public interface UserDAO{
void save();
}
public class UserDAOImpl implements UserDAO{
public void save(){
....
}
}
public class UserServiceImpl implements UserService{
private UserDAO userDAO = new UserDAOImpl();
public void reg(){
userDAO.save();
}
}
----------------------------------------------------
public class UserDAOJDBCImpl implements UserDAO{
public void save(){
....
}
}
public class UserServiceImpl implements UserService{
private UserDAO userDAO;
public void reg(){
userDAO.save();
....
}
}
我们在UserServiceImpl中不再实例化DAO对象
从Spring容器中获得
搭建Spring环境
1、添加依赖
<!-- https://mvnrepository.com/artifact/org.springframework/spring-web -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.3.18.RELEASE</version>
</dependency>
2、编写bean
package cn.cqie.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private String uname;
private String upwd;
}
3、编写配置文件
先将模板在idea中生成
<?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">
<!--
User user = new User();
<bean> 声明实例化对象的信息
id 对象的名称
class 对象的类型
-->
<bean id="user" class="cn.cqie.pojo.User"></bean>
</beans>
4、测试获取user对象
package cn.cqie.test;
import cn.cqie.pojo.User;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class AppTest {
@Test
public void test(){
ApplicationContext applicationContext =
new ClassPathXmlApplicationContext("app.xml");
User user = (User) applicationContext.getBean("user");
System.out.println("AppTest.test"+user);
user.setUname("yx");
user.setUpwd("123");
System.out.println(user);
}
}
IOC容器介绍
BeanFactory
在没有获取容器中实例时,不实例化对应的对象
BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("app.xml"));
BeanFactory beanFactory1 = new XmlBeanFactory(new FileSystemResource("d:/app.xml"));
ApplicationContext
ApplicationContext applicationContext2 = new FileSystemXmlApplicationContext("d:/app.xml");
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("app.xml");
ApplicationContext applicationContext3 = new AnnotationConfigApplicationContext(JavaConfig.class);
User user = (User) applicationContext3.getBean("user");
System.out.println("AppTest.test"+user);
user.setUname("yx");
user.setUpwd("123");
System.out.println(user);
容器生成时,就会实例化配置文件中声明的对象
ApplicationContext从BeanFactory派生出来的
ApplicationContext增加了以下功能
-
国际化(MessageSource)
-
访问资源,如URL和文件(ResourceLoader)
-
载入多个(有继承关系)上下文 ,使得每一个上下文都专注于一个特定的层次,比如应用的web层
-
消息发送、响应机制(ApplicationEventPublisher)
-
AOP(拦截器)
获取实例的简单的底层原理
package cn.cqie.util;
import cn.cqie.pojo.User;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class MyClassPathXmlApplicationContext {
Map<String,Object> container = new HashMap<>();
public MyClassPathXmlApplicationContext(String resource){
//获得resource对应的文件路径 或者 输入流
InputStream inputStream = null;
try {
inputStream = new FileInputStream(new File(resource));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
//使用xml 解析技术(dom4j)读取xml文件的信息
SAXReader reader = new SAXReader();
try {
Document document = reader.read(inputStream);
//读出标签<bean>、属性(id 、 class) 及值 (user 、 cn.cqie.pojo.User)
Element rootElement = document.getRootElement();
List<Element> elements = rootElement.elements();
for (Element element:elements){
System.out.println(element.getName());
List<Attribute> attributes = element.attributes();
String id = "";
String clazz = "";
for (Attribute attribute:attributes){
if(attribute.getName().equals("id")){
id = attribute.getValue();
System.out.println("id :"+id);
}else{
if(attribute.getName().equals("class")){
clazz = attribute.getValue();
System.out.println("clazz :"+ clazz);
}
}
}
//使用反射生成实例
Class<?> aClass = Class.forName(clazz);
Object obj = aClass.newInstance();
//使用Map存储id和对应的实例
container.put(id,obj);
}
} catch (DocumentException | ClassNotFoundException | InstantiationException | IllegalAccessException e) {
e.printStackTrace();
}
}
public Object getBean(String id){
return container.get(id);
}
public static void main(String[] args) {
MyClassPathXmlApplicationContext context = new MyClassPathXmlApplicationContext("f:/app2.xml");
User user = (User) context.getBean("user");
user.setUname("tcx");
System.out.println("user :"+user);
}
}
Bean的概念
Spring中Bean就是一个类的实例
<bean id="" class="" />
Bean的生成方式有三种:
1、构造器生成
<?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">
<!-- 通过构造器生成
cn.cqie.pojo.User 必须有为空的构造器
-->
<bean id="user" class="cn.cqie.pojo.User"/>
</beans>
@Test
public void testConstructor(){
System.out.println(66);
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("app2.xml");
User user = (User) applicationContext.getBean("user");
user.setUname("constructor ");
System.out.println(user);
}
2、静态工厂
//UserStaticFactor.java
package cn.cqie.util;
import cn.cqie.pojo.User;
public class UserStaticFactor {
public static User getUser(){
return new User();
}
}
<?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">
<!-- 通过静态工厂生成
User user = UserStaticFactor.getUser();
-->
<bean id="user2" class="cn.cqie.util.UserStaticFactor" factory-method="getUser"/>
</beans>
@Test
public void testStaticFactor(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("app2.xml");
User user2 = (User) applicationContext.getBean("user2");
user2.setUname("static factory");
System.out.println(user2);
}
3、实例工厂
// UserInstanceFactor.java
package cn.cqie.util;
import cn.cqie.pojo.User;
public class UserInstanceFactor {
public User getUser(){
return new User();
}
}
<?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">
<!-- 实例化工厂构造
UserInstanceFactor userInstanceFactor = new UserInstanceFactor();
User user = userInstanceFactor.getUser();
-->
<bean id="userInstanceFactor" class="cn.cqie.util.UserInstanceFactor" />
<bean id="user3" factory-bean="userInstanceFactor" factory-method="getUser"/>
</beans>
@Test
public void testInstanceFactor(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("app2.xml");
User user3 = (User) applicationContext.getBean("user3");
user3.setUname("Instance factor ");
}
Bean的作用域范围
scope有如下五个取值:
singleton:单例的(默认的),使用singleton定义的Bean是单例的,每次调用getBean都是调用的同一个对象。只要IoC容器一创建就会创建Bean的实例。
prototype:多例的,每次通过Spring IoC容器获取prototype定义的Bean时,容器都将创建一个新的Bean实例。创建时不会实例该Bean,只有调用getBean方法时,才会实例化。
request:作用于web的请求范围,在每一次HTTP请求时,容器会返回Bean的同一个实例,对不同的HTTP请求则会产生一个新的Bean,而且该Bean仅在当前HTTP Request内有效。
session:作用于web的会话范围,在一次HTTP Session中,容器会返回该Bean的同一个实例,对不同的HTTP请求则会产生一个新的Bean,而且该Bean仅在当前HTTP Session内有效。
global-session:作用于集群环境的会话范围(全局会话范围),在一个全局的HTTP Session中,容器返回Bean的同一个实例。当不是集群环境时,它就是session。
<?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="cn.cqie.pojo.User" scope="prototype"/>
</beans>
@Test
public void testScope(){
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("app3.xml");
User user = (User) applicationContext.getBean("user");
User user2 = (User) applicationContext.getBean("user");
System.out.println(user==user2);
}
依赖注入概述
dao层和service层 impl
代码
package cn.cqie.dao.impl;
import cn.cqie.dao.UserDAO;
public class UserDAOImpl implements UserDAO 以上是关于Spring笔记的主要内容,如果未能解决你的问题,请参考以下文章
初识Spring源码 -- doResolveDependency | findAutowireCandidates | @Order@Priority调用排序 | @Autowired注入(代码片段
Spring boot:thymeleaf 没有正确渲染片段
What's the difference between @Component, @Repository & @Service annotations in Spring?(代码片段
spring练习,在Eclipse搭建的Spring开发环境中,使用set注入方式,实现对象的依赖关系,通过ClassPathXmlApplicationContext实体类获取Bean对象(代码片段
Spring Rest 文档。片段生成时 UTF-8 中间字节无效 [重复]
解决spring-boot启动中碰到的问题:Cannot determine embedded database driver class for database type NONE(转)(代码片段