Spring学习笔记

说明:文中加粗表示重点,标题已经小标题除外。

Day1

JavaEE三层技术:web层、service层、dao层
每一层所使用的技术:
       web:Servlet+JSP ->SpringMVC或者Struts2(已经不怎么用了),一般都用SpringMVC
       service:JavaBean
       dao:JDBC+DBUtils ->可以用框架MyBatis取代(对于数据库的操作),Hibernate(很老了)也可以
Spring是贯穿三层的技术,比较重要
       SSH:Spring + Struts2 + Hibernate(不怎么常用了)
       SSM:Spring + SpringMVC + MyBatis (现在比较常用)

Spring其实是一个容器,用来管理对象。包括了new对象、销毁对象、获取对象。

JavaBean的规范:
       1.成员变量私有化,提供get/set方法
       2.提供无参构造器
       3.重写toString、equals、hashCode方法
       4.不能用final修饰

快速搭建Spring容器:
       1.导包
       2.创建类
       3.配置文件 --配置管理对象 —bean
              a.导入约束
              b.创建文件xml —引入约束内容 (src/applicationContext.xml)
              c.管理对象
       xml文件中的标签标示有很多对象,导入约束后会有很多xml,xmlns等;标示一个对象

4.开启容器获得对象,详细看代码

		// 1.开启容器
		//一般看见名字很长的
		//ClassPath默认是src文件夹下
		ClassPathXmlApplicationContext ac = 
				new ClassPathXmlApplicationContext("applicationContext.xml");
		// 2.获得对象
		//方法1
		User u1 = (User) ac.getBean("user"); // bean的名字
		User u2 = (User) ac.getBean("user"); // bean的名字
		User u3 = (User) ac.getBean("user"); // bean的名字
		
		// 方法2,只适用于容器中只有一个User对象
		//User u2 = ac.getBean(User.class);
		
		System.out.println(u2);
		//== 判断的是地址是否相同,也就是是否为同一个对象
		System.out.println(u2 == u1);//结果返回true,因为容器就创建好了一个对象(单例子模式),你调用就返回,因此是同一个对象
		ac.close();

Spring核心思想/核心模块/两个重要的组成部分:IOC AOP
       IOC(inverse of control):反转控制------传统new对象的工作,交给容器来做;并通过反射的原理,调用类的构造器(默认是无参构造器);对象的属性/依赖注入也交给Spring容器来做。
              DI思想:依赖注入
                     方法有:依赖注入
                                    构造器注入
                                   set方法注入
                                   字段注入

AOP:

       Spring管理对象:默认是容器启动就创建好对象,并采用单例模式,因此只创建一个对象,每次调用就返回。当然也可以使用prototype(多例模式),使用对象时会返回多个对象。

Spring创建对象的3种方式:
       第一种方式是简单的无参构造器创建对象
       第二种静态工厂方法,由于是createUser()是静态方法,因此可以直接用类调用
       其中第3种工厂方法创建对象时,由于getUser()是普通方法,调用时需要对象,因此需要先创建一个工厂bean(工厂对象),然后使用factor-bean属性调用创建方法。
代码示例如下:

	<!--1. 通过无参构造器创建对象 -->
	<bean class="b_create.User" name="user"></bean>
	
	<!-- 工厂:抽象工厂、简单工厂、工厂方法 -->
	<!--2. 静态工厂的方式创建对象 -->
	<bean class="b_create.StaticFactory" name="user1" 
		factory-method="createUser"></bean>
	
	<!-- 3.工厂方法 -->
	<bean name="factory" class="b_create.StaticFactory"></bean>
	<bean name="user2" factory-method="getUser" 
		factory-bean="factory"></bean>

<!-- ----------------------------------------------------------------------------->

	public class StaticFactory {
		// 提供静态方法,获得user对象
		public static User createUser() {
			return new User();
		}
		
		// 工厂方法,提供一个普通方法,获得user对象
		public User getUser() {
			return new User();
		}
	}

set注入方式引用类型和简单类型
       set注入方式需要类有set方法,然后用property标签实现基本类型属性的注入。当属性是一个对象时,首先需要创建一个对象bean,然后采用引用的方式ref来注入属性。示例代码如下:

<!-- 注入1:set方式 -->
	<bean class="c_inject.User" name="user">
		<!-- 简单类型,都是直接赋值
			 简单类型:String 八大基本数据类型/包装类
		 -->
		<property name="name" value="lucy"></property>
		<property name="age" value="18"></property>
		<property name="sex" value="f"></property>
		<!-- 引用类型的注入 -->
		<property name="car" ref="car"></property>
	</bean>
	<!-- 注册car对象 -->
	<bean name="car" class="c_inject.Car">
		<property name="name" value="兰博基尼"></property>
		<property name="color" value="黄色"></property>
	</bean>

其他三种注入方式
构造器注入了解,其中P命名空间与SPEL表达式注入基本不用

<!-- 方式2:构造器注入 -->
	<bean name="user1" class="c_inject.User">
		<!-- 全参 -->
		<constructor-arg type="java.lang.String" value="tom"></constructor-arg>
		<constructor-arg type="int" value="20"></constructor-arg>
		<constructor-arg type="char" value="m"></constructor-arg>
		<constructor-arg type="c_inject.Car" ref="car"></constructor-arg>
	</bean>
	<bean name="user2" class="c_inject.User">
		<!-- name, age | String , int, 默认只看类型 
			 index属性:表示当前参数是构造器中第几个参数
		 -->
		<constructor-arg type="java.lang.String" value="jack"></constructor-arg>
		<constructor-arg type="Integer" value="21" index="0"></constructor-arg>
	</bean>
	<!-- 方式3:p命名空间注入 - 先添加p命名约束 -->
	<bean name="user3" class="c_inject.User"
		p:age="23" p:name="rose" p:sex="f"
		p:car-ref="car" ></bean>
	<!-- 方式4:SPEL表达式注入,引用其他对象的属性 -->
	<bean name="user4" class="c_inject.User">
		<property name="name" value="#{user3.name}"></property>
	</bean>

复杂类型注入
       复杂类型主要是类中包含了List,Set,Map,Property等类型,需要进行注入。一般在property标签下面会有这些类型,按照给定格式进行注入即可。其中注意property和Map一起都是以键值对的形式存值的。
示例代码如下;

<bean name="user" class="d_comp.User">
		<!-- 如果数组中只有一个元素,可以使用value -->
		<!-- <property name="arr" value="11"></property> -->
		<property name="arr">
			<array>
				<value>11</value>
				<value>12</value>
				<value>13</value>
				<!-- <ref bean=""/> -->
			</array>
		</property>
		<property name="list">
			<list>
				<value>lucy</value>
				<value>tom</value>
				<value>jack</value>
			</list>
		</property>
		<!-- <property name="set" ref="car"></property> -->
		<property name="set">
			<set>
				<ref bean="car"/>
				<ref bean="car1"/>
			</set>
		</property>
		<property name="pros">
			<props>
				<prop key="driver">com.mysql.jdbc.Driver</prop>
				<prop key="username">root</prop>
			</props>
		</property>
		
		
	</bean>
	
	<bean name="car" class="d_comp.Car">
		<property name="name" value="玛莎拉蒂"></property>
		<property name="color" value="绿色"></property>
	</bean>
	<bean name="car1" class="d_comp.Car">
		<property name="name" value="劳斯莱斯"></property>
		<property name="color" value="紫色"></property>
	</bean>

Day2

一、注解配置
注解用来取代配置文件 —context
       a.导包:spring-aop
       b.添加命名空间/约束
              1.eclipse先导入约束文件 context
              2.配置文件中引入约束
       c.开启注解配置
详细过程:
1.首先需要在applicationContext.xml配置文件中开启注解扫描

<!-- 开启注解扫描
		 base-package:基本扫描包,包中的注解才能识别
		 com.zzxx.crm.web
		 com.zzxx.crm.service
		 com.zzxx.crm.dao
	 -->
	<context:component-scan base-package="a_annotation"></context:component-scan>

2.在需要管理的类前加上注解,即可使用该类,其中包括了变量的注入

@Component("u1")  // spring容器中就已经管理了user对象,自动命名user
//	@Repository		// dao
//	@Service		// service
//	@Controller		// web
@Scope("singleton") // bean-scope属性
public class User {
	private String name;
	@Value("18")
	private int age;
	@Value("f")
	private char sex;
	
	/*
	 * @Autowired // 自动装配 - bean-ref,一般会自动注入进来
	 * @Qualifier("car1")   指定注入的对象名 bean-name
	@Resource(name = "car1") // 取代上面两个注解
	private Car car;  // 引用类型
	
	public User() {
		super();
	}
	@Value("lucy") // 简单类型的注入
	// 严格符合set注入的思想,但是为了方便起见,都会直接使用在变量上
	public void setName(String name) {
		this.name = name;
	}
	@PostConstruct // init-method
	public void init () {
		
	} 
	@PreDestroy // destroy-method
	public void destroy() {
		
	}
	public Car getCar() {
		return car;
	}

	public void setCar(Car car) {
		this.car = car;
	}
......

二、Spring对Junit的支持
       在JUnit的tset方法运行之前,开启容器,并且把需要的对象注入进来
       a.导包: spring-test, spring-aop,JUnit
       b.SpringJUnit4ClassRunner
示例代码:

// JUnitTest运行之前打开容器
@RunWith(SpringJUnit4ClassRunner.class)
// 指定配置文件路径
@ContextConfiguration("classpath:b_junit/applicationContext.xml")
public class JUnitTest {
	@Autowired
	private User user;
	@Test
	public void test02() {
		System.out.println(user);
	}
	@Autowired
	private Car car;
	@Test
	public void test03() {
		System.out.println(car);
	}
}

三、AOP:面向切面编程 -----代理模式
AOP的一些基本概念:
在这里插入图片描述
       即AOP面向切面编程表示多个service之间在纵向有公共部分,因此在横向添加一些公共的代码,来实现增强代码的目的。

代理模式:目的是生成代理对象,并对被代理对象的方法进行增强
       动态代理:代理对象和被代理对象拥有相同的父接口
       cglib代理:代理对象继承被代理对象(被代理对象不能是final)

代码示例:
1.ProxyDemo类,用来添加代理,并实现被代理对象的方法的增强。

public class ProxyDemo {
	@Test
	// 动态代理 =》观光代码
	public void test01() {
		// 动态代理的原理:代理对象和被代理对象拥有相同的父接口
		// 被代理对象UserServiceImpl
		// newProxyInstance获得代理对象
		// 代理对象:包含了原来的方法,并且将原来的方法进行了增强
		/* loader:类加载器,被代理对象的类加载器
		 * interfaces:被代理对象的超级接口
		 * InvocationHandler:执行方法的处理器
		 */
		UserService us = new UserServiceImpl();
		UserService proxy = (UserService) Proxy.newProxyInstance(UserServiceImpl.class.getClassLoader(), 
				UserServiceImpl.class.getInterfaces(), 
				new InvocationHandler() {
					/**
					 * 
					 * @param proxy 代理对象
					 * @param method 要增强的方法
					 * @param args 调用方法的参数
					 * @return 增强后的方法返回值,原来方法的返回值
					 * @throws Throwable
					 */
					public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
						// 公共代码
						System.out.println("开启事务");
						// 执行原来的方法
						Object o = method.invoke(us, args);
						System.out.println("提交事务");
						return o;
					}
				});
//		proxy.transfer();
//		us.transfer();
		
//		System.out.println(us.addUser());
		System.out.println(proxy.addUser());
		System.out.println(proxy instanceof UserServiceImpl);
	}
	
	@Test
	// CGlib 代理
	public void test02() {
		// CGlib 代理原理:代理对象继承被代理对象
	}
	
}

2.公共父接口

public interface UserService {
	void transfer();
	
	int addUser();
}

3.被代理对象-----实现父接口的类

public class UserServiceImpl implements UserService {

	@Override
	public void transfer() {
		System.out.println("转账操作");
	}

	@Override
	public int addUser() {
		System.out.println("添加用户");
		return 10;
	}

}

四、SpringAOP准备
SpringAOP名词解释:
       Joinpoint(连接点):目标对象中,所有可以增强的方法
       Pointcut(切入点):目标对象中,已经增强的方法
       Advice(通知/增强):增强的代码
       Target(目标对象):被代理的对象
       Weaving(织入):将通知应用到切入点的过程
        aspect(切面):切入点+通知

SpringAOP配置文件过程:
       1.配置目标对象
       2.配置通知
       3.准备织入,形成切面
              a.配置切入点
              b.织入通知

示例代码:
1.配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">
	
	<!-- 1.配置目标对象 -->
	<bean class="e_springaop.UserServiceImpl" name="userService"></bean>
	<!-- 2.配置通知 -->
	<bean class="e_springaop.MyAdvice" name="myAdvice"></bean>
	
	<!-- 3.准备织入,形成切面 -->
	<!-- 准备工作:导包(aop/aspects/weaver/aopalliance)、引入约束aop(命名空间中的aop约束) -->
	<aop:config>
		<!-- 配置切入点-要增强什么方法
			void e_springaop.UserServiceImpl.insertUser(String)
			* e_springaop.UserServiceImpl.insertUser(String)
			* e_springaop.UserServiceImpl.*(String)
			* e_springaop.UserServiceImpl.*(..)
			* e_springaop.*ServiceImpl.*(..)
			使用通配符来修改
			
		 -->
		<aop:pointcut expression="execution(* e_springaop.*ServiceImpl.*(..))" id="pc"/>
		<!-- 织入 -->
		<aop:aspect ref="myAdvice">
			<aop:before method="before" pointcut-ref="pc"/>
			<aop:after method="after" pointcut-ref="pc"/>
			<aop:after-returning method="afterReturn" pointcut-ref="pc"/>
			<aop:after-throwing method="afterThrow" pointcut-ref="pc"/>
		</aop:aspect>
	</aop:config>
	
</beans>

2.通知类

// 通知类
	// - 前置通知		切入点之前执行
	// - 后置通知		切入点之后执行
	// - 环绕通知		切入点执行之前、之后都执行
	// - 后置通知		切入点方法正常执行结束后才执行的
	// - 异常通知		捕获到切入点异常执行
public class MyAdvice {
	// 前置通知 - 在连接点调用之前执行的
	public void before() {
		System.out.println("前置通知");
	}
	
	public void after() {
		System.out.println("后置通知1");
	}
	
	public void afterReturn() {
		System.out.println("后置通知2");
	}
	public void afterThrow() {
		System.out.println("捕获到异常通知");
	}
}

3.测试类

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:e_springaop/applicationContext.xml")
public class SpringAOPTest {
	@Resource(name="userService")
	private UserService userService;
	@Test
	public void test01() {
		userService.findUserById();
	}
}

接口类和被代理类与上面的例子类似,不再赘述。

五、JDBC模板使用
Spring和数据库进行整合的模板
       JDBC --JdbcTemplate --类,操作数据库
       Hibernate – HibernateTemplate
       MyBatis

使用JdbcTemplate模板,首先需要导包— pring-jdbc、spring-tx
部分示例代码:

@Repository("accountDao")
public class AccountDaoImpl implements AccountDao {
//	@Resource(name="queryRunner")  -- 没法处理事务
//	private QueryRunner queryRunner;
	@Resource(name="jdbcTemplate")
	private JdbcTemplate jt;
	
	public void decrease(int fromId, double money) {
		String sql = "update account set money = money - ? where id = ?";
		jt.update(sql, money, fromId);
	}

	public void increase(int toId, double money) {
		String sql = "update account set money = money + ? where id = ?";
		jt.update(sql, money, toId);
	}

}

Day3

Spring事务管理。。。。。后续再细细了解

Maven第一天笔记 -----一个用java写的管理平台,用jar索引来管理jar包,非常方便
1.Maven目录结构
       bin —工具/命令
       boot —支持包
       conf —配置文件,settings.xml
       lib —库类 jar
       Maven中央仓库地址: https://mvnrepository.com/

2.Maven配置
       首先下载Maven,然后在本地创建一个文件夹,名称为repository。然后修改maven文件夹下conf文件夹下的settings.xml配置,把其中的D:/apache-maven-3.6.3/repository从注释中取出来,然后改成自己刚刚建的本地仓库路径即可。
然后将Maven与eclipse绑定即可使用。

3.maven工程目录结构
       target:编译后的文件存储目录
       src:源代码
              main:真正的Java源代码/配置文件放在这边
                     webapp:以前的webContent
                     resources:以前放在src中的配置文件
              java:以前的src.存放java源代码
              (resources/java最终编译路径是合并的)
              test:所有的Junit测试都放在这边
       pom.xml:maven核心配置文件,用来添加插件、添加jar包

4.maven生命周期(了解)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值