Git Product home page Git Product logo

java_learnning_trip's Introduction

置顶 👍

最新 🆕

Typescripts 总结 0 💬 2021-06-29 08:22:54

🏷️ : 面试, typescript

总结TypeScript在项目开发中的应用实践体会

条件类型

type B<T> = T extends string ? '1' : '2'

const a: B<s
[更多>>>](https://github.com/hsipeng/note/issues/96)
---

#### [前端知识总结](https://github.com/hsipeng/note/issues/95) <sup>0 :speech_balloon:</sup> 	 2020-08-08 08:40:10
:label: : [面试](https://github.com/hsipeng/note/labels/%E9%9D%A2%E8%AF%95), [前端](https://github.com/hsipeng/note/labels/%E5%89%8D%E7%AB%AF), [:+1:置顶](https://github.com/hsipeng/note/labels/%3A%2B1%3A%E7%BD%AE%E9%A1%B6)
自己整理出来的针对 P6 级别的前端知识体系

欢迎批评指正

地址是➡️  [http://hsipeng.github.io/fed](http://hsipeng.github.io/fed)
[更多>>>](https://github.com/hsipeng/note/issues/95)
---

#### [Redux 实现原理](https://github.com/hsipeng/note/issues/94) <sup>0 :speech_balloon:</sup> 	 2020-05-12 16:27:43
:label: : [react](https://github.com/hsipeng/note/labels/react), [redux](https://github.com/hsipeng/note/labels/redux)
```javascript
function createStore(reducer, state = null){
    let listeners = [];
    let getState = () => state;
    let subscribe = listener =>
[更多>>>](https://github.com/hsipeng/note/issues/94)
---

#### [ssl 生成 ssl 证书](https://github.com/hsipeng/note/issues/93) <sup>0 :speech_balloon:</sup> 	 2020-05-12 15:30:58
:label: : [linux](https://github.com/hsipeng/note/labels/linux), [ssl](https://github.com/hsipeng/note/labels/ssl)
## nginx 安装

sudo apt get install nginx


nginx 配置

server { listen 80 default; server_name domain; location / {

React 单元测试 0 💬 2019-09-16 08:17:22

🏷️ : react, 单元测试, jest

为何必须做单元测试

  • 单元测试对于任何 React 项目(及其他任何项目)来说都是必须的
  • 我们需要自动化的测试套件,根本目标是支持随时随地的代码调整、持续改进,从而提升团队响应力
  • 使用 TDD 开发是得到好的单元测试的唯一途径
  • 好的单元测试具备几大特征:不关注内部实现 更多>>>

分类 🗃️

词云, 点击展开详细分类

☁️ 词云 ☁️ 点击词云展开详细分类:point_down:

👍置顶 3:newspaper: - [前端知识总结](#95) 0 💬 - [网站工具Api搜集整理](#78) 0 💬 - [Flutter 学习整理](#76) 1 💬
🖼️封面 0:newspaper:
2B青年 4:newspaper: - [初爱](#23) 0 💬 - [关山月](#22) 0 💬 - [雪中歌](#21) 0 💬 - [江上有感](#18) 0 💬
axios 1:newspaper: - [基于 Promise 的 HTTP 请求客户端,axios](#13) 0 💬
babel 1:newspaper: - [react webpack babel 三剑客错误处理](#53) 0 💬
bug 0:newspaper:
centos 1:newspaper: - [ssh 权限问题](#41) 0 💬
coffeeScript 1:newspaper: - [CoffeeScript 基础知识](#8) 0 💬
component 1:newspaper: - [## Re: Zero 学习一个组件](#43) 0 💬
css 1:newspaper: - [前端开发,从草根到英雄(总结)](#12) 0 💬
Curry 1:newspaper: - [柯里化](#29) 0 💬
D3 1:newspaper: - [D3 与 React ](#63) 0 💬
Data Analysis 1:newspaper: - [Data Analysis with Python——01](#75) 0 💬
Data Analysis with Python 9:newspaper: - [Data Analysis with Python——09](#89) 1 💬 - [Data Analysis with Python——08](#88) 0 💬 - [Data Analysis with Python——07](#87) 0 💬 - [Data Analysis with Python——06](#86) 0 💬 - [Data Analysis with Python——05](#85) 0 💬 - [Data Analysis with Python——04](#84) 0 💬 - [Data Analysis with Python——03](#83) 0 💬 - [Data Analysis with Python——02](#82) 0 💬 - [Data Analysis with Python——01](#81) 0 💬
duplicate 0:newspaper:
enhancement 0:newspaper:
ES6 3:newspaper: - [ES6 数组去重](#57) 0 💬 - [ES6 知识点整理](#34) 0 💬 - [【译】ES 6 代理 (Proxy) 简介 ](#32) 0 💬
eslint 1:newspaper: - [vscode AutoSave With Prettier ](#64) 0 💬
flutter 1:newspaper: - [Flutter 学习整理](#76) 1 💬
gh-pages 1:newspaper: - [travis ci 持续集成](#26) 0 💬
git 2:newspaper: - [travis ci 持续集成](#26) 0 💬 - [git 安装与使用](#14) 0 💬
help wanted 0:newspaper:
html 1:newspaper: - [前端开发,从草根到英雄(总结)](#12) 0 💬
invalid 0:newspaper:
java 3:newspaper: - [Oracle 与 MySql 区别(笔记)](#6) 0 💬 - [java基础知识笔记(2)](#5) 0 💬 - [java基础知识笔记(1)](#4) 0 💬
javascript 11:newspaper: - [前端常用算法梳理](#77) 0 💬 - [ES6 数组去重](#57) 0 💬 - [函数式编程](#49) 0 💬 - [javascript 转换](#38) 0 💬 - [算法](#36) 0 💬 - [this的指向](#31) 0 💬 - [闭包的应用](#30) 0 💬 - [手撸一个 redux 实现](#28) 0 💬 - [javascript 精粹](#27) 0 💬 - [基于 Promise 的 HTTP 请求客户端,axios](#13) 0 💬 - [前端开发,从草根到英雄(总结)](#12) 0 💬
jest 1:newspaper: - [React 单元测试](#92) 0 💬
jsonp 1:newspaper: - [Promise Jsonp](#50) 0 💬
koa 1:newspaper: - [Koa 中间件](#60) 0 💬
linux 2:newspaper: - [ssl 生成 ssl 证书](#93) 0 💬 - [Ubuntu安装BTSync](#7) 1 💬
MiniProgram 1:newspaper: - [小程序ios 安卓兼容性](#65) 0 💬
Mybatis 1:newspaper: - [java SSM框架的搭建](#25) 0 💬
mysql 1:newspaper: - [Mysql 备忘](#45) 0 💬
nodejs 3:newspaper: - [Promise Jsonp](#50) 0 💬 - [travis ci 持续集成](#26) 0 💬 - [基于 Promise 的 HTTP 请求客户端,axios](#13) 0 💬
npm 1:newspaper: - [publish package to npmjs.com](#66) 0 💬
NumPy 1:newspaper: - [Data Analysis with Python——01](#75) 0 💬
poem 4:newspaper: - [初爱](#23) 0 💬 - [关山月](#22) 0 💬 - [雪中歌](#21) 0 💬 - [江上有感](#18) 0 💬
prettier 1:newspaper: - [vscode AutoSave With Prettier ](#64) 0 💬
promise 1:newspaper: - [基于 Promise 的 HTTP 请求客户端,axios](#13) 0 💬
python 14:newspaper: - [Data Analysis with Python——09](#89) 1 💬 - [Data Analysis with Python——08](#88) 0 💬 - [Data Analysis with Python——07](#87) 0 💬 - [Data Analysis with Python——06](#86) 0 💬 - [Data Analysis with Python——05](#85) 0 💬 - [Data Analysis with Python——04](#84) 0 💬 - [Data Analysis with Python——03](#83) 0 💬 - [Data Analysis with Python——02](#82) 0 💬 - [Data Analysis with Python——01](#81) 0 💬 - [python数据分析之性能度量](#80) 0 💬 - [python数据分析之数据缺失](#79) 0 💬 - [Data Analysis with Python——01](#75) 0 💬 - [python 环境](#74) 0 💬 - [python之pyenv版本控制](#15) 0 💬
question 0:newspaper:
Raspberry Pi 0:newspaper:
Re: Zero 2:newspaper: - [Re: Zero JSX 回调函数中的 this](#44) 0 💬 - [## Re: Zero 学习一个组件](#43) 0 💬
react 14:newspaper: - [Redux 实现原理](#94) 0 💬 - [React 单元测试](#92) 0 💬 - [D3 与 React ](#63) 0 💬 - [React 单元测试](#62) 0 💬 - [React 服务端渲染](#61) 0 💬 - [redux 写法详解](#59) 0 💬 - [react webpack babel 三剑客错误处理](#53) 0 💬 - [一个可用于生产环境的开发框架的搭建](#48) 0 💬 - [项目结构详解](#47) 0 💬 - [Re: Zero JSX 回调函数中的 this](#44) 0 💬 - [## Re: Zero 学习一个组件](#43) 0 💬 - [无状态函数式组件](#37) 0 💬 - [面试纪要](#33) 0 💬 - [手撸一个 redux 实现](#28) 0 💬
redux 3:newspaper: - [Redux 实现原理](#94) 0 💬 - [redux 写法详解](#59) 0 💬 - [手撸一个 redux 实现](#28) 0 💬
Spring 1:newspaper: - [java SSM框架的搭建](#25) 0 💬
SpringMVC 1:newspaper: - [java SSM框架的搭建](#25) 0 💬
ssh 1:newspaper: - [ssh 权限问题](#41) 0 💬
ssl 1:newspaper: - [ssl 生成 ssl 证书](#93) 0 💬
SSM 1:newspaper: - [java SSM框架的搭建](#25) 0 💬
ssr 1:newspaper: - [React 服务端渲染](#61) 0 💬
this 1:newspaper: - [this的指向](#31) 0 💬
Travis CI 1:newspaper: - [travis ci 持续集成](#26) 0 💬
typescript 2:newspaper: - [Typescripts 总结](#96) 0 💬 - [vue with typescript](#73) 0 💬
ubuntu 2:newspaper: - [Ubuntu使用dnsmasq作本地DNS缓存](#24) 0 💬 - [Ubuntu安装BTSync](#7) 1 💬
vscode 1:newspaper: - [vscode AutoSave With Prettier ](#64) 0 💬
vue 2:newspaper: - [vue with typescript](#73) 0 💬 - [vue全面介绍--全家桶(vue笔记一)](#10) 0 💬
Webpack 10:newspaper: - [webpack to umd package](#72) 0 💬 - [webpack 4 - webpack-merge to config dev prod environment quickly](#71) 0 💬 - [webpack4-HMR with webpack-dev-server](#70) 0 💬 - [webpack4-Atuo serve dist file](#69) 0 💬 - [# webpack4-command line without config file](#68) 0 💬 - [webpack4 - Basic config](#67) 0 💬 - [react webpack babel 三剑客错误处理](#53) 0 💬 - [webpack 3.5.5 文档 再读](#52) 0 💬 - [webpack 4 ](#39) 0 💬 - [Webpack 入门](#11) 0 💬
wechat 1:newspaper: - [小程序ios 安卓兼容性](#65) 0 💬
wontfix 0:newspaper:
函数式编程 1:newspaper: - [函数式编程](#49) 0 💬
前端 3:newspaper: - [前端知识总结](#95) 0 💬 - [前端常用算法梳理](#77) 0 💬 - [柯里化](#29) 0 💬
单元测试 2:newspaper: - [React 单元测试](#92) 0 💬 - [React 单元测试](#62) 0 💬
取整 1:newspaper: - [javascript 转换](#38) 0 💬
学习笔记 1:newspaper: - [javascript 精粹](#27) 0 💬
小程序 3:newspaper: - [小程序热区](#58) 0 💬 - [小程序组件及组件事件转发](#56) 0 💬 - [小程序热区](#55) 0 💬
开源 0:newspaper:
技术 0:newspaper:
数据分析 13:newspaper: - [如何炼就数据分析的思维?](#91) 0 💬 - [数据分析惯用的5种思维方法](#90) 0 💬 - [Data Analysis with Python——09](#89) 1 💬 - [Data Analysis with Python——08](#88) 0 💬 - [Data Analysis with Python——07](#87) 0 💬 - [Data Analysis with Python——06](#86) 0 💬 - [Data Analysis with Python——05](#85) 0 💬 - [Data Analysis with Python——04](#84) 0 💬 - [Data Analysis with Python——03](#83) 0 💬 - [Data Analysis with Python——02](#82) 0 💬 - [Data Analysis with Python——01](#81) 0 💬 - [python数据分析之性能度量](#80) 0 💬 - [python数据分析之数据缺失](#79) 0 💬
数据缺失 1:newspaper: - [python数据分析之数据缺失](#79) 0 💬
文艺 4:newspaper: - [初爱](#23) 0 💬 - [关山月](#22) 0 💬 - [雪中歌](#21) 0 💬 - [江上有感](#18) 0 💬
新生 1:newspaper: - [拿到公司电脑,之后要做些什么](#46) 0 💬
无状态组件 1:newspaper: - [无状态函数式组件](#37) 0 💬
日记 6:newspaper: - [对未来的思考](#20) 0 💬 - [谁说的青春无悔](#19) 0 💬 - [生活,需要一些仪式感 ](#17) 0 💬 - [2015-09-08-反思](#16) 0 💬 - [2017-05-19-总结](#3) 0 💬 - [热爱工作热爱生活](#2) 0 💬
柯里 1:newspaper: - [柯里化](#29) 0 💬
框架 1:newspaper: - [一个可用于生产环境的开发框架的搭建](#48) 0 💬
热区 1:newspaper: - [小程序热区](#55) 0 💬
电影 2:newspaper: - [无问西东](#51) 0 💬 - [姜文的一步之遥](#9) 0 💬
知识点 1:newspaper: - [ES6 知识点整理](#34) 0 💬
算法 2:newspaper: - [前端常用算法梳理](#77) 0 💬 - [算法](#36) 0 💬
翻译 1:newspaper: - [【译】ES 6 代理 (Proxy) 简介 ](#32) 0 💬
读书笔记 1:newspaper: - [生活,需要一些仪式感 ](#17) 0 💬
闭包 1:newspaper: - [闭包的应用](#30) 0 💬
面试 5:newspaper: - [Typescripts 总结](#96) 0 💬 - [前端知识总结](#95) 0 💬 - [面试纪要](#33) 0 💬 - [this的指向](#31) 0 💬 - [柯里化](#29) 0 💬
音乐 0:newspaper:
项目 1:newspaper: - [项目结构详解](#47) 0 💬

java_learnning_trip's People

Contributors

hsipeng avatar

Watchers

 avatar

Forkers

lester2525

java_learnning_trip's Issues

java中常见的几种排序方法

  • 1)冒泡排序:
    依次比较相邻的两个元素,通过一次比较把未排序序列中最大(或最小)的元素放置在未排序序列的末尾。
public class BubbleSort { 
public static void sort(int data[]) { 
for (int i = 0; i < data.length -1; i++) { 
for (int j = 0; j < data.length - i - 1; j++) { 
if (data[j] > data[j + 1]) { 
int temp = data[j]; 
data[j] = data[j + 1]; 
data[j + 1] = temp; 
}

        }  
    }  
}  
}
  • 2)选择排序:
    每一次从待排序的数据元素中选出最小(或最大)的一个元素,顺序放在已排好序的数列的最后,直到全部待排序的数据元素排完。
public class SelectionSort { 
public static void sort(int data[]) { 
int minVal; 
int minIndex; 
for (int i = 0; i < data.length - 1; i++) { 
minVal = data[i]; 
minIndex = i; 
for (int j = i + 1; j < data.length; j++) { 
if (data[j] < minVal) { 
minVal = data[j]; 
minIndex = j; 
} 
} 
if (minVal != data[i] && minIndex != i) { 
data[minIndex] = data[i]; 
data[i] = minVal; 
} 
}

}  
}
  • 3)快速排序:
    通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
public class QuickSort { 
public static void sort(int data[], int start, int end) { 
if (end - start <= 0) { 
return; 
} 
int last = start; 
for (int i = start + 1; i <= end; i++) { 
if (data[i] < data[start]) { 
int temp = data[++last]; 
data[last] = data[i]; 
data[i] = temp; 
} 
} 
int temp = data[last]; 
data[last] = data[start]; 
data[start] = temp; 
sort(data, start, last - 1); 
sort(data, last + 1, end); 
}

}

30.事务策略

spring只处理运行时异常,并且负责回滚,
如果遇到检查异常,spring不回滚。

Mybatis

jdbc的缺点

  • 实现松耦合,获取数据连接比较困难
  • 实现增删改功能,重复性代码较多
  • 结果集需要手动封装
  • 传统的JDBC连接数据库需要频繁的创建和关闭连接

mybatise是一个持久层框架

自动对象关系映射,使用SQL直接操作数据库
mybatis是半自动的ORM(对象关系映射)
##Mybatis组件

  • .配置sqlMapconfig.xml 核心配置文件
    导入DTD约束
  • 数据库配置
  • 配置UserMapper.xml
  • 创建sqlsession

26.如何获取目标方法参数

需求:获取目标方法的参数并进行记录

execution(* cn.service..*(..)) and args(name,age) and target(target) and @annotation(hello)"

获取目标参数:

args(name,age)

获取目标对象

target(target)  target获取目标对象

获取注解内容

@annotation(hello)

ps:匹配参数需要加and,args写法固定,args(name,age),与通知总的参数一致,否则报错.
target(target) target获取目标对象,@annotation(hello) ,获取注解内容。hello为通知中接收的参数。

21.SpringAOP(Aspect Orient Programming)-面向切面编程

名称介绍:

切面(Aspect):完成特定功能的类就是一个切面,切面是通知和切入点的结合
连接点(JionPoint):客户端调用的
通知(Advice):切面中的方法
切入点(PointCut):匹配连接点的断言
目标对象(Target Object):真正调用的方法

AOP编程

 场景设计:用AOP 完成事务控制
步骤:
       1.导入jar包
       2.导入头文件
       3.定义切面
       4.编写配置

AOP执行原理
当一个对象执行时,会进行切入点表达式,匹配成功,就为该类创建代理对象,(如果该类有接口则JDK动态创建,如果没有则cglib创建。)代理对象执行时,会执行通知。

过滤器和拦截器的区别

过滤器和拦截器的区别:
  ①拦截器是基于Java的反射机制的,而过滤器是基于函数回调。
  ②拦截器不依赖与servlet容器,过滤器依赖与servlet容器。
  ③拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用。
  ④拦截器可以访问action上下文、值栈里的对象,而过滤器不能访问。
  ⑤在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次。
  ⑥拦截器可以获取IOC容器中的各个bean,而过滤器就不行,这点很重要,在拦截器里注入一个service,可以调用业务逻辑。

有return的情况下try catch finally的执行顺序(最有说服力的总结)

1、不管有木有出现异常,finally块中代码都会执行;
2、当try和catch中有return时,finally仍然会执行;
3、finally是在return后面的表达式运算后执行的(此时并没有返回运算后的值,而是先把要返回的值保存起来,管finally中的代码怎么样,返回的值都不会改变,任然是之前保存的值),所以函数返回值是在finally执行前确定的;
4、finally中最好不要包含return,否则程序会提前退出,返回值不是try或catch中保存的返回值。
举例:
情况1:try{} catch(){}finally{} return;
显然程序按顺序执行。
情况2:try{ return; }catch(){} finally{} return;
程序执行try块中return之前(包括return语句中的表达式运算)代码;
再执行finally块,最后执行try中return;
finally块之后的语句return,因为程序在try中已经return所以不再执行。
情况3:try{ } catch(){return;} finally{} return;
程序先执行try,如果遇到异常执行catch块,
有异常:则执行catch中return之前(包括return语句中的表达式运算)代码,再执行finally语句中全部代码,
最后执行catch块中return. finally之后也就是4处的代码不再执行。
无异常:执行完try再finally再return.
情况4:try{ return; }catch(){} finally{return;}
程序执行try块中return之前(包括return语句中的表达式运算)代码;
再执行finally块,因为finally块中有return所以提前退出。
情况5:try{} catch(){return;}finally{return;}
程序执行catch块中return之前(包括return语句中的表达式运算)代码;
再执行finally块,因为finally块中有return所以提前退出。
情况6:try{ return;}catch(){return;} finally{return;}
程序执行try块中return之前(包括return语句中的表达式运算)代码;
有异常:执行catch块中return之前(包括return语句中的表达式运算)代码;
则再执行finally块,因为finally块中有return所以提前退出。
无异常:则再执行finally块,因为finally块中有return所以提前退出。

最终结论:任何执行try 或者catch中的return语句之前,都会先执行finally语句,如果finally存在的话。
如果finally中有return语句,那么程序就return了,所以finally中的return是一定会被return的,
编译器把finally中的return实现为一个warning。

下面是个测试程序
public class FinallyTest
{
public static void main(String[] args) {

	System.out.println(new FinallyTest().test());;
}

static int test()
{
	int x = 1;
	try
	{
		x++;
		return x;
	}
	finally
	{
		++x;
	}
}

}
结果是2。
分析:
在try语句中,在执行return语句时,要返回的结果已经准备好了,就在此时,程序转到finally执行了。
在转去之前,try中先把要返回的结果存放到不同于x的局部变量中去,执行完finally之后,在从中取出返回结果,
因此,即使finally中对变量x进行了改变,但是不会影响返回结果。
它应该使用栈保存返回值。

Spring 懒加载 lazy-init

由于spring在启动时会逐行解析,为每一个bean都会创建对象,这样的方式不是很高效
如果容器启动时只创建必须要使用的对象,当其他对象调用getBean方法时创建。

  • lazy-init="default" 默认是逐行解析的 加载容器时创建对象
  • lazy-init="false" 表示在spring启动时,立刻进行实例化
  • lazy-init="true" 懒加载 getBean方法时创建

beans 中 defult-lazy-init="default | true | false" 全局懒加载

bean中设置懒加载比beans 中设置懒加载优先级高

当多例启用时,懒加载是无效的,getBean调用时创建对象。

lazy-init="default" scope="prototype" lazy-init无效 多例默认启用懒加载

在Spring中对象只维护单例对象,只负责单例对象的生命周期,如果对象为多例的时候,Spring只管创建该对象交给用户使用后将不再管理该对象。

ps:
Spring 只管单例,多列对象统统懒加载

17.注解

  • @autowire
    1.内部有两种匹配规则,根据属性名称匹配bean的ID,
    如果匹配不成功,则按照属性类型Class匹配。如果还没有匹配成功,则报错。
    2.指定Bean的ID匹配
    @qualifier(value="dogA")
    @Autowired 根据bean 类型从spring 上线文中进行查找,注册类型必须唯一,否则报异常。
    3.@resource
    可以完成@autowire的所有功能,@resource 允许通过bean 名称id,或bean 类型class,两种方式进行查找,如果spring 上下文中没有找到该类型的bean 时, 才会使用new SoftPMServiceImpl();
  • 4.类型的注解
    类的注解作用是代替bean的。简化Spring配置文件。
    使用步骤:
    -- 开启包扫描 <context:component-scan base-package="beans"/>
    -- 添加注解 @component
    开启包扫描后,spring会先扫描指定的包,包内的子孙对象中含有@component的,并为其创建对象,并且默认条件下生产的id就是类名首字母小写。并存入spring容器自身维护的map中。
  • 5.同类型注解(@component)
    @controller --web层注解
    @repository --dao层
    @service --service层
    @scope ---单列,多例
    @lazy(false) ---懒加载
    @PostConstruct --init注解
    @PreDestroy ---destory注解
    component 默认实现了BeanNameAware中的setBeanName方法,将名字命名为类名的小写。反射到对应的名字。
Person ---> person  

pErson ---> pErson

  • 6.注解属性赋值
    @value(“xxx”)
    配置文件中的属性赋值
    @value(“${xxx}”),xxx为配置文件中的key
    @value(“#{@xxx}”),xxx为applicationContext.xml文件中的key
    通过@value注解 实现基本类型赋值与集合赋值(集合赋值需要util包)
    -7.引入外部配置文件
<context:property-placeholder location="classpath:/user.properties"/>

其中location表示具体路径

9.Spring 创建对象的方式

  • 默认构造方法创建对象(用的最多)
    Spring中默认创建对象的方式,就是通过无参构造创建对象。

  • 通过静态工厂创建对象
    静态工厂中,最为关键的部分就是静态方法,如果没有静态方法,那么必然报错。
    通过静态方法创建对象,和通过类名.static方法的方式一致

  • 实例工厂创建对象

  • Spring工厂创建对象
    public class SpringFactory implements FactoryBean

Spring 简介

SSM:
Spring
1.Spring的 IOC--控制反转 和 DI--依赖注入(Spring的核心**)
2.Spring的注解形式
3.Spring的AOP(面向切面工程)
4.Spring和JDBC进行整合(MySQL)
5.Spring的声明式的事务处理

1.什么是框架?
框架是就是将一些重复的重要的代码进行模块化集成。
方便以后直接进行调用,目的提高开发效率。

2.Spring框架
Spring的主要目的就是简化代码的开发,并且能够整合现阶段所有的主流框架,起到一个粘合剂的作用。
在项目中使用Spring可以一站式的开发编程。编程效率大大提高,其中IOC和DI以及AOP是Spring的两大核心技术。

3.Spring的IOC
IOC叫做控制反转,就是将对象的创建权利发生反转,之前自己手动创建对象,现在变成由Spring容器帮助创建生成新的对象。从此程序员无需关注对象的创建过程,无需关注对象的生命周期。
Person p1=new Person(); 手动创建对象
Person p2=Spring容器.get***();由Spring容器创建

4.Spring的IOC实现步骤
1.创建实体类
bean----只要被Spring管理的就是一个bean
2.,编写配置文件()
配置文件的名称:
最好使用Spring默认的名称
applicationContext.xml
1)编写配置文件的头
2)编写配置文件的实体内容
3.启动Spring的容器
4.从容器中获取对象,调用方法,完成相应功能

8.别名标签

别名标签 name属性中书写 起别名的bean的ID alias 中英文都可以

给一个bean起多个名字,就需要用到别名标签

spring多例与单例

Spring通过容器创建对象时,默认单例(singleton),需要设置scpe,prototype(多例对象)
通过getBean()方法直接获取。

23.AOP中的通知类型

前置通知(Before advice):在目标方法执行之前执行(记录日志)
后置通知(After returning advice):在目标方法执行之后执行
异常通知(After throwing advice):在目标方法执行时,如果抛异常,就会执行异常通知
最终通知(After (finally) advice):不管目标方法是否执行,都会执行的通知
以上四个通知,一般只起到程序流转作用
环绕通知(Around advice):在目标方法执行前后都会执行,环绕通知是最为强大的也是用的最多的。

20.动态代理

态代理的核心其实就是代理对象的生成,
即Proxy.newProxyInstance(classLoader, proxyInterface, handler)

JDK代理

     - 1.能够实现代码的松耦合,解决代码重复问题
     - 2.需要被代理者必须实现接口
     - 3.动态代理模式只能处理一类业务,如果处理业务不同,需要重新编写动态代理。

cglib

使用动态字节码生成技术实现AOP原理是在运行期间目标字节码加载后,生成目标类的子类,将切面逻辑加入到子类中,所以使用Cglib实现AOP不需要基于接口

cglib和jdk的区别

- jdk创建代理对象,速度较快,cglib创建代理对象的速度较慢
- jdk的动态代理需要实现 --- InvocationHandler接口
- cglib 创建代理对象,底层是通过二进制码创建的,并且生成的代理对象都是目标对象的子类,无接口可以直接生成代理对象。

24.通知中的参数

1.除了环绕通知之外,其余通知全部使用import org.aspectj.lang.JoinPoint;
而环绕通知使用的是import org.aspectj.lang.ProceedingJoinPoint;
规定:如果通知总有多个参数,JoinPoint或者ProceedingJoinPoint必须位于参数第一位否则报错
2.配置文件中的返回参数应与通知中的参数一致

32.实物一致性

同时插入两张表

	public void addUser(User user) throws SQLException{
		
			Person person = new Person();
			person.setId(user.getId());
			person.setName(user.getName());
			personService.addPerson(person);
			userDao.addUser(user);
		
	}

10. Spring 对象销毁和初始化

初始化

init-method="init" 

销毁

destroy-method="destory"

ApplicationContext 是一个接口,不提供close方法,ClassPathXmlApplicationContext可以关闭

19.静态代理(**)

场景设计:

   数据库的事务在每一个系统中都需要用到,在service层中控制事务

传统设计模式的缺点

1.事务处理的代理大量重复,开发效率低
2.处理业务的代码,和处理事务的代码强耦合在一起,非常的危险。

理想设计模式

处理事务的代码尽可能的少重复。
处理业务逻辑的代码和处理事务的代码分离。

静态代理模式

 解决业务层事务代码紧耦合的问题
 #### 缺点
         1.处理业务代码重复
         2.需要为添加事务的类都创建代理模式

Servlet 2.5 与Servlet3.0

完成了一个使用注解描述的Servlet程序开发。
使用@WebServlet将一个继承于javax.servlet.http.HttpServlet的类定义为Servlet组件。
@WebServlet有很多的属性:
  1、asyncSupported: 声明Servlet是否支持异步操作模式。
  2、description:   Servlet的描述。
  3、displayName: Servlet的显示名称。
  4、initParams: Servlet的init参数。
 5、name:     Servlet的名称。
  6、urlPatterns:   Servlet的访问URL。
  7、value:    Servlet的访问URL。
 Servlet的访问URL是Servlet的必选属性,可以选择使用urlPatterns或者value定义。
像上面的Servlet3Demo可以描述成@WebServlet(name="Servlet3Demo",value="/Servlet3Demo")。
也定义多个URL访问:
 如@WebServlet(name="Servlet3Demo",urlPatterns={"/Servlet3Demo","/Servlet3Demo2"})
 或者@WebServlet(name="AnnotationServlet",value={"/Servlet3Demo","/Servlet3Demo2"})
或者 @WebServlet("/CheckServlet")

2017.07.07

###今日总结
代理模式
客户---中介---房主
还复习了spring的注解的使用,然后练习一些demo

###明日计划
明天阅读相关spring,springmvc书籍,熟悉基本操作,为下个礼拜的项目做准备。

15.DI(依赖注入)

依赖注入一般可以是 基本类型,字符串,对象的引用,集合(list,set,map)

  • 1.seter方法注入
    与setxxx后面xxx名称保持一致。
    1. 集合注入
      List
      Set
      Map
  • 3.对象的引入
    通过ref可以为引用类型赋值,ref值写的是bean的ID

构造方法注入
注意 构造参数和索引个数要保持一致,如果不一致必然报错

  • index参数位置从0开始
  • name 构造方法中参数的名称 ---4.0版本后使用
  • ref 引入类型
  • value 直接赋值
  • type 赋值类型 --spring中类型会自动转换
    虽然通过index和name属性都可以为属性赋值,但最好使用index这样没有导入源码的情况下,页面保证赋值正确。

Parent 属性
spring创建对象时,没有指明父子关系,需要使用Parent属性来指定,这时才会自动维护。

Spring Bean生命周期

我们知道一个对象的生命周期:创建(实例化-初始化)-使用-销毁,而在spring中,Bean对象周期当然遵从这一过程,但是Spring提供了许多对外接口,允许开发者对三个过程(实例化、初始化、销毁)的前后做一些操作。
  这里就实例化、初始化区别做一个说明,在Spring Bean中,实例化是为bean对象开辟空间(具体可以理解为构造函数的调用),初始化则是对属性的初始化,说的具体点,这里的属性初始化应该是属性的注入(构造函数也可以有属性的初始化语句,但不属于这一部分),属性注入是通过setter方法注入属性(不管是注解方式还是bean配置property属性方式,其实质都是通过属性的setter方法实现的)。

相关接口、方法说明

Bean自身方法:init-method/destroy-method,通过为配置文件bean定义中添加相应属性指定相应执行方法。
Bean级生命周期接口:BeanNameAware、BeanFactoryAware、InitializingBean和DiposableBean这些接口的方法。每个Bean选择实现,可选择各自的个性化操作。
容器级生命周期接口方法:这个包括了InstantiationAwareBeanPostProcessor 和 BeanPostProcessor 这两个接口实现(前者继承自后者),一般称它们的实现类为“后处理器”(其实我觉得这个名称对新手有误导的意思),这些接口是每个bean实例化或初始化时候都会调用。
工厂后处理器接口方法:这些方法也是容器级别的,但它们是在上下文装置配置文件之后调用,例如BeanFactoryPostProcessor、 CustomAutowireConfigurer等。
(这里说一点,这些类名都很长,有的也挺相似,学习的话要仔细看清楚哪个是哪个。)

2017.07.06

##今日总结
今天主要学习注解的使用,以及注解需要依赖的beans头文件,还有就是一些基本注解@component,@service,@controller,@scope等的使用,然后就是一些bean的自动装配问题。

##明日计划
明天计划继续深入学习spring,然后就是应该要多看看书了,时不我待,努力扩充自己的知识面。

面向对象重写(override)与重载(overload)区别

一、重写(override)

override是重写(覆盖)了一个方法,以实现不同的功能。一般是用于子类在继承父类时,重写(重新实现)父类中的方法。

重写(覆盖)的规则:

1、重写方法的参数列表必须完全与被重写的方法的相同,否则不能称其为重写而是重载.

2、重写方法的访问修饰符一定要大于被重写方法的访问修饰符(public>protected>default>private)。

3、重写的方法的返回值必须和被重写的方法的返回一致;

4、重写的方法所抛出的异常必须和被重写方法的所抛出的异常一致,或者是其子类;

5、被重写的方法不能为private,否则在其子类中只是新定义了一个方法,并没s有对其进行重写。

6、静态方法不能被重写为非静态的方法(会编译出错)。

override就是子类将父类的方法重新实现了一遍。
new就是说这个方法就是子类自己的,跟父类没有任何继承关系关系,仅仅是重名 

    public class A
    {
        public virtual string Function()
        {
            return "1";
        }
    }
    public class B : A
    {
        public override string Function()
        {
            return "2";
        }
    }
    public class C : A
    {
        public new string Function()
        {
            return "3";
        }
    }

    public class JustForTest
    {
        public void DoTest()
        {
            B b = new B();
            C c = new C();

            Console.WriteLine(b.Function());
            Console.WriteLine(c.Function());
            Console.WriteLine((b as A).Function());//这两个就体现出来了,B还是调用自己,返回2
            Console.WriteLine((c as A).Function());//C调用的是基类,返回0
        }
    }

二、overload是重载,一般是用于在一个类内实现若干重载的方法,这些方法的名称相同而参数形式不同。

重载的规则:

1、在使用重载时只能通过相同的方法名、不同的参数形式实现。不同的参数类型可以是不同的参数类型,不同的参数个数,不同的参数顺序(参数类型必须不一样);

2、不能通过访问权限、返回类型、抛出的异常进行重载;

3、方法的异常类型和数目不会对重载造成影响;

多态的概念比较复杂,有多种意义的多态,一个有趣但不严谨的说法是:继承是子类使用父类的方法,而多态则是父类使用子类的方法。

一般,我们使用多态是为了避免在父类里大量重载引起代码臃肿且难于维护。

举个例子:

public class Shape

{

   public static void main(String[] args){

     Triangle tri = new Triangle();

     System.out.println("Triangle is a type of shape? " + tri.isShape());// 继承

     Shape shape = new Triangle();

     System.out.println("My shape has " + shape.getSides() + " sides."); // 多态

     Rectangle Rec = new Rectangle();

     Shape shape2 = Rec;

     System.out.println("My shape has " + shape2.getSides(Rec) + " sides."); //重载

   }

   public boolean isShape(){

     return true;

   }

   public int getSides(){

     return 0 ;

   }

   public int getSides(Triangle tri){ //重载

     return 3 ;

   }

   public int getSides(Rectangle rec){ //重载

    return 4 ;

   }

}

class Triangle extends Shape

{

   public int getSides() { //重写,实现多态

     return 3;

   }

}

class Rectangle extends Shape

{

   public int getSides(int i) { //重载

    return i;

   }

}

注意Triangle类的方法是重写,而Rectangle类的方法是重载。对两者比较,可以发现多态对重载的优点:

如果用重载,则在父类里要对应每一个子类都重载一个取得边数的方法;

如果用多态,则父类只提供取得边数的接口,至于取得哪个形状的边数,怎样取得,在子类里各自实现(重写)。

11.容器中对象的生命周期

  • 1.调用构造方法创建对象
  • 2.调用init方法初始化属性
  • 3.调用目标方法完成相应功能
  • 4.调用销毁方法做收尾工作

25.通知执行规则

1.当异常通知执行时,,后置通知将不会执行。异常通知和后置通知是互斥的。
2.最终通知无论如何都会被执行
3.当目标方法执行时出现异常,环绕通知的后半部分将不会被执行
4.当环绕通知遇到后置通知时,如果后置通知想得到返回值,那么环绕通知必须添加return将返回值返回
5.当多个环绕通知同时执行时,其顺序是嵌套结构
joinPoint.procceed()的作用有两个
1.如果有下一个通知,就执行下一个通知
2.如果没有下一个通知,则执行目标方法

16.简化Spring配置

  • 1.简化注入方式
    自动装配(autowire),引用引用类型的属性注入都可以使用自动装配完成注入。
autowire="byName" 通过属性名进行注入
    原理:
      1.首先会去寻找当前bean的set方法
      2.setCat变形--->cat     (set去掉,并且首字母小写)
      3. 根据cat属性名称匹配bean中的标签ID
      4. 如果匹配成功则正确注入,否则为null

autowire="byType" 通过属性的类型进行注入

原理:
  1.首先会去寻找当前bean的set方法
  2.setCat变形--->cat     (set去掉,并且首字母小写)-->找class类型
  3.根据class类型与bean中的class匹配

如果匹配成功则注入,反之为null

  • autowire 全局装配
    全局装配后,bean单个配置会失效,以全局为准。
default-autowire="default"

18.代理模式

客户---- 中介----房东

1.客户需求:租房子
2.代理:帮客户出租房屋,带客户看房,收取中介费
3.房东:提供房子

特点:
1.定义接口(接口定义的方法将来会被实现)
2.完成本职工作(执行目标方法)
3.完成额外的操作

JSON

JSON 语法规则

JSON 语法是 JavaScript 对象表示法语法的子集。
数据在名称/值对中
数据由逗号分隔
大括号保存对象
中括号保存数组

格式转换

  • 将数组转换为json
JSONArray jsonArray = JSONArray.fromObject(arr);
  • 将List转换为json
JSONArray jsonArray = JSONArray.fromObject(list);
  • 将Map转换为json
JSONArray jsonArray = JSONArray.fromObject(map);
  • 将对象转换为json

对象必须有getter和setter,排除使用jsonconfig

//JSON配置文件,转化配置规则
JsonConfig jsonConfig = new JsonConfig();
//排除属性值
jsonConfig.setExcludes(new String[]{"addr"});
System.out.println(product);
		
JSONObject jsonObject = JSONObject.fromObject(product,jsonConfig);
System.out.println(jsonObject);
  • json转换为对象
//将json串转换为对象
String jString = "{'id':1,'name':'iphone8','price':8888}";
JSONObject jsonObject = JSONObject.fromObject(jString);
Product product = (Product) jsonObject.toBean(jsonObject,Product.class);
System.out.println(product);

22.切入点的表达式

within()按类进行匹配 控制的力度较粗
within(cn.service.UserServiceImpl) 只能匹配到UserServiceImpl这个类
within(cn.service.*)匹配当前包下的全部类(一层)

execution
execution()控制细粒度比较细,能够控制到方法和参数级别
execution(返回值类型 包名.类名.方法名(参数类型))
案例:
例1:<aop:pointcut expression="execution(int service.UserServiceImpl.add())" id="txPointcut"/>
返回值int 包名service 类名UserServiceImpl 方法名 add
例2:<aop:pointcut expression="execution(* service..add())" id="txPointcut"/>
返回值任意类型 包名service 类名任意类 方法名 add
例3:<aop:pointcut expression="execution(
service...add())" id="txPointcut"/>
返回值任意类型 包名service 包下所有子孙类的add方法
例4: <aop:pointcut expression="execution(
service...add(int,String))" id="txPointcut"/>
返回值任意类型 包名service 包下所有参数类型为int和String的add方法
例5:<aop:pointcut expression="execution(
service...add(..))" id="txPointcut"/>
返回值任意类型 包名service 包底下任意参数类型的add方法
例6:<aop:pointcut expression="execution(
cn.service...(..))" id="txPointcut"/>
返回值任意类型 包名service底下任意类任意参数类型的任意方法
如果.去掉更加方便
例6(改):<aop:pointcut expression="execution(
cn.service..*(..))" id="txPointcut"/>
返回值任意类型 包名service底下任意类任意参数类型的任意方法

实现缓存处理

要求:
如果用户根据id查询用户时,相同id缓存
1.通知的选择:环绕通知 控制目标方法的执行
2.数据的存储使用:Map

Jquery

  • 1.介绍

  • 2.版本

  • 3.js插件Aptana
    js 实现页面js自动提示

  • 4.语法
    $(" ").action()

  • 5.类型转化:
    jQuery 通过数组存储对象信息。

  • 5.jquery选择器

jQuery 的选择器可谓之强大无比,这里简单地总结一下常用的元素查找方法

$("#myELement") 选择id值等于myElement的元素,id值不能重复在文档中只能有一个id值是myElement所以得到的是唯一的元素
$("div") 选择所有的div标签元素,返回div元素数组
$(".myClass") 选择使用myClass类的css的所有元素
$("*") 选择文档中的所有的元素,可以运用多种的选择方式进行联合选择:例如$("#myELement,div,.myclass")

层叠选择器:

$("form input") 选择所有的form元素中的input元素
$("#main > *") 选择id值为main的所有的子元素
$("label + input") 选择所有的label元素的下一个input元素节点,经测试选择器返回的是label标签后面直接跟一个input标签的所有input标签元素
$("#prev ~ div") 同胞选择器,该选择器返回的为id为prev的标签元素的所有的属于同一个父元素的div标签

基本过滤选择器:

$("tr:first") 选择所有tr元素的第一个
$("tr:last") 选择所有tr元素的最后一个
$("input:not(:checked) + span")

过滤掉:checked的选择器的所有的input元素

$("tr:even") 选择所有的tr元素的第0,2,4... ...个元素(注意:因为所选择的多个元素时为数组,所以序号是从0开始)

$("tr:odd") 选择所有的tr元素的第1,3,5... ...个元素
$("td:eq(2)") 选择所有的td元素中序号为2的那个td元素
$("td:gt(4)") 选择td元素中序号大于4的所有td元素
$("td:ll(4)") 选择td元素中序号小于4的所有的td元素
$(":header")
$("div:animated")

内容过滤选择器:

$("div:contains('John')") 选择所有div中含有John文本的元素
$("td:empty") 选择所有的为空(也不包括文本节点)的td元素的数组
$("div:has(p)") 选择所有含有p标签的div元素
$("td:parent") 选择所有的以td为父节点的元素数组

可视化过滤选择器:

$("div:hidden") 选择所有的被hidden的div元素
$("div:visible") 选择所有的可视化的div元素

属性过滤选择器:

$("div[id]") 选择所有含有id属性的div元素
$("input[name='newsletter']") 选择所有的name属性等于'newsletter'的input元素

$("input[name!='newsletter']") 选择所有的name属性不等于'newsletter'的input元素

$("input[name^='news']") 选择所有的name属性以'news'开头的input元素
$("input[name$='news']") 选择所有的name属性以'news'结尾的input元素
$("input[name*='man']") 选择所有的name属性包含'news'的input元素

$("input[id][name$='man']") 可以使用多个属性进行联合选择,该选择器是得到所有的含有id属性并且那么属性以man结尾的元素

子元素过滤选择器:

$("ul li:nth-child(2)"),$("ul li:nth-child(odd)"),$("ul li:nth-child(3n + 1)")

$("div span:first-child") 返回所有的div元素的第一个子节点的数组
$("div span:last-child") 返回所有的div元素的最后一个节点的数组
$("div button:only-child") 返回所有的div中只有唯一一个子节点的所有子节点的数组

表单元素选择器:

$(":input") 选择所有的表单输入元素,包括input, textarea, select 和 button

$(":text") 选择所有的text input元素
$(":password") 选择所有的password input元素
$(":radio") 选择所有的radio input元素
$(":checkbox") 选择所有的checkbox input元素
$(":submit") 选择所有的submit input元素
$(":image") 选择所有的image input元素
$(":reset") 选择所有的reset input元素
$(":button") 选择所有的button input元素
$(":file") 选择所有的file input元素
$(":hidden") 选择所有类型为hidden的input元素或表单的隐藏域

表单元素过滤选择器:

$(":enabled") 选择所有的可操作的表单元素
$(":disabled") 选择所有的不可操作的表单元素
$(":checked") 选择所有的被checked的表单元素
$("select option:selected") 选择所有的select 的子元素中被selected的元素

选取一个 name 为”S_03_22″的input text框的上一个td的text值
$(”input[@ name =S_03_22]“).parent().prev().text()

名字以”S_”开始,并且不是以”R”结尾的
$(”input[@ name ^='S
']“).not(”[@ name $='_R']“)

一个名为 radio_01的radio所选的值
$(”input[@ name =radio_01][@checked]“).val();

$("A B") 查找A元素下面的所有子节点,包括非直接子节点
$("A>B") 查找A元素下面的直接子节点
$("A+B") 查找A元素后面的兄弟节点,包括非直接子节点
$("A~B") 查找A元素后面的兄弟节点,不包括非直接子节点

  1. $("A B") 查找A元素下面的所有子节点,包括非直接子节点

例子:找到表单中所有的 input 元素

HTML 代码:

Name: Newsletter: jQuery 代码:

$("form input")
结果:

[ , ]

  1. $("A>B") 查找A元素下面的直接子节点
    例子:匹配表单中所有的子级input元素。

HTML 代码:

Name: Newsletter: jQuery 代码:

$("form > input")
结果:

[ ]

  1. $("A+B") 查找A元素后面的兄弟节点,包括非直接子节点
    例子:匹配所有跟在 label 后面的 input 元素

HTML 代码:

Name: Newsletter: jQuery 代码:

$("label + input")
结果:

[ , ]

  1. $("A~B") 查找A元素后面的兄弟节点,不包括非直接子节点
    例子:找到所有与表单同辈的 input 元素

HTML 代码:

Name: Newsletter: jQuery 代码:

$("form ~ input")
结果:

[ ]

27.切面注解

  • 开启切面注解
<aop:aspectj-autoproxy/>
  • 定义切面
    @aspect
  • 定义切入点
    1,空方法
@Pointcut(value="execution(* cn.service..*(..))")

2.在通知内部定义
通知内部加入切入点
该切入点只绑定当前方法。

  • 定义通知
    @before(value="pointcut()")
    @around
    @AfterReturning
    @AfterThrowing
    @after

  • 在注解中获取目标方法参数
    1) 通过空方法获取参数

@Pointcut(value="execution(* cn.service..*(..)) && args(year)")
	public void pointcut(int year){
		
	}

2)在通知内部定义(用的最多)

	@Before(value="execution(* cn.service..*(..)) && args(year) && target(t)")
	public void before(int year,Object t) {
		System.out.println("前置通知");
		System.err.println("year is "+year);
		System.out.println("目标对象:"+t);
	}

2017.07.12-demo练习

  • 1.异常:
    代码结构如图所示
    PersonServlet
    PersonService
    PersonDao
    用异常通知捕获servlet的所有的方法抛出的异常:
    目标对象所在的类 cn.servlet.PersonServlet
    抛出异常所在的方法 save()
    抛出异常的名称 XxxException
    异常信息 message

    意义:
    异常处理类和业务逻辑类完全松耦合。
    时刻捕获生产生产环境中所有的错误,实时监控该系统,异常收集。

@AfterThrowing(value="execution(* cn.servlet..*(..))",throwing="throwable")
	public void  afterThrow(JoinPoint joinPoint,Throwable throwable) {
		Class target = joinPoint.getTarget().getClass();
		String method = joinPoint.getSignature().getName();
		System.out.println("目标对象为:"+target);
		System.out.println("目标方法:"+method);
		System.err.println("异常类:"+throwable.getClass());
		System.err.println("异常:"+throwable.getMessage());
	}
  • 2.方法执行的时间
    计算servlet的各个类的各个方法的执行时间
    1.类的名称
    2.方法的名称
    3.执行的时间
    控制台输出

    意义:用来监控程序的性能问题

@Around(value="execution(* cn.servlet..*(..))")
	public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
		System.out.println("类名:"+joinPoint.getTarget().getClass());
		System.out.println("方法名:"+joinPoint.getSignature().getName());
		long start = System.currentTimeMillis();
		Object object = joinPoint.proceed();
		long end = System.currentTimeMillis();
		System.out.println("程序运行时间为:" +(end-start)+"ms");
		return object;
	}
  • 3.事务
    public class PresonServiceImpl{
    @transactional
    public void savePerson(){

      	}
      	public void queryPerson(){
    
      	}
      }
      写一个切面来完成
    

PersonAspect.java

@Component
@Aspect
public class PersonAspect {
	
	@Resource
	private TranscationManager tx;//事务流程控制类
	
	@Around(value="execution(* cn.service..*(..)) && @annotation(tran)")//切面定义,引入自定义注解
	public Object around(ProceedingJoinPoint joinPoint,Transactional tran) throws Throwable {
		tx.begin();
		Object object = joinPoint.proceed();
		tx.commit();
		return object;
	}
	
	@AfterThrowing(value="execution(* cn.service..*(..))",throwing="throwable")
	public void  afterThrow(JoinPoint joinPoint,Throwable throwable) {
		tx.rollback();//异常回滚操作
		Class target = joinPoint.getTarget().getClass();
		String method = joinPoint.getSignature().getName();
		System.out.println("目标对象为:"+target);
		System.out.println("目标方法:"+method);
		System.err.println("异常类:"+throwable.getClass());
		System.err.println("异常:"+throwable.getMessage());
	}
}

@Transactional.java

@Target(ElementType.METHOD)//指定运行在方法上
@Retention(RetentionPolicy.RUNTIME)//在何时运行
public @interface Transactional {
	
}
  • 4.模拟权限控制
    public class PersonServiceImpl{
    @PrivilegeInfo(name="saveperson") //要访问PersonSserviceImpl中的savePerson方法必须具备"saveperson"的权限
    public void savePerson(){
    xxxxxxxxx
    }
    }
    ListPrivilege:name 用户所拥有的权限
    写一个切面:
    把客户端用户拥有的权限要在切面中获取到

PersonAspect.java

@Component
@Aspect
public class PersonAspect {
	
	
	
	@Around(value="execution(* cn.service..*(..))")
	public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
		Object object = null;
		//3.获取用户列表
		List<String> pList = Privilege.getpList();
		//4.获取方法上的注释
		/**
		 * 获取方法名称
		 */
		String methodName = joinPoint.getSignature().getName();
		//获取目标方法参数,返回值是Object数组
		Object[] args = joinPoint.getArgs();
		//将Object转化为class类型,方便下面操作
		Class[] argClass = new Class[args.length];
		for(int i =0;i<args.length;i++){
			argClass[i] = args[i].getClass();
		}
		//获取目标对象
		Class targetClass = joinPoint.getTarget().getClass();
		//获取method对象
		Method method = targetClass.getMethod(methodName, argClass);
		
		//判断有没有注解
		if(method.isAnnotationPresent(( PrivilegeInfo.class))){
			//该方法上有权限注解
			PrivilegeInfo info = method.getAnnotation(PrivilegeInfo.class);
			//获取权限注解的值
			String name = info.name();
			//判断
			if(pList.contains(name)){
				System.out.println("权限SSS");
				object= joinPoint.proceed();
			}else {
				System.out.println("您没有权限");
			}
		}else {
			object= joinPoint.proceed();
		}
		
		
		
		return object;
	}

}

Privilege.java

public class Privilege {
	private static List<String> pList = new ArrayList<String>();

	public static List<String> getpList() {
		return pList;
	}

	public static void setpList(List<String> prList) {
		pList = prList;
	}
	
}

或者可以用ThreadLocal
ThreadPri.java

public class ThreadPri {
//在当前线程内共享数据,实现线程安全
	private static ThreadLocal<List<String>> threadLocal = new ThreadLocal<List<String>>();

	public static void setList(List<String> lsit){
		threadLocal.set(lsit);
	}
	public static List<String> getList(){
		return threadLocal.get();
	}
	
}

@PrivilegeInfo.java

@Target(ElementType.METHOD)//指定运行在方法上
@Retention(RetentionPolicy.RUNTIME)//在何时运行
public @interface PrivilegeInfo {
	public String name();
}

JQuery的AJAX

  document.getElementById("b1").onclick=function () {
    //AJAX调用
    /**
      创建xmlHttpRequest
      绑定回调函数
      与服务器建立连接
      发送数据
      回调函数处理相应的数据
    */
    var xmlhttp = createXMLHttpRequest();
    xmlhttp.onreadystatechange = function () {
      if(xmlhttp.readyState == 4){
        if(xmlhttp.status == 200){
          var callback = xmlhttp.responseText;
          alert(callback)
        }
      }
    }

    xmlhttp.open("POST","../servlet/AjaxServlet",true);
    xmlhttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
    xmlhttp.send("name=张三");

  }

  function createXMLHttpRequest() {

    try{
       // IE7+, Firefox, Chrome, Opera, Safari 浏览器执行的代码
     xmlhttp = new XMLHttpRequest();
    }catch(tryMS){
      try{
        //IE6, IE5 浏览器执行的代码
        xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
      }catch(otherMS){
        try{
          xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
        }catch(failed){
          xmlhttp = null;
          //无法获得xmlhttp对象

        }
      }
    }
    return xmlhttp;
  }

2017.07.22

今日总结

主要学习了spring 几种通知的注解的使用,主要方法包括空方法注解,和通知内注解,然后就是切面中返回值的传递和获取目标对象。

明日计划

java差不多学完了,主要就是再看看书,复习复习,将一些常用的函数,方法,等知识熟记,然后投入到项目中去,应用,同时也要努力学习前端方面的知识,综合发展。

2017.07.04

总结

今天学习了DI(依赖注入),分别基本数据类型,和String ,集合类,还有对象的引用。

##明日计划
明天计划熟悉框架,开始研究怎么写建材项目。

jdbc连接Oracle、mysql等主流数据库的驱动类和url

jdbc连接Oracle、mysql等主流数据库的驱动类和url

  • oracle
    driverClass:oracle.jdbc.driver.OracleDriver
    url:jdbc:oracle:thin:@127.0.0.1:1521:dbname

  • mysql
    driverClass:com.mysql.jdbc.Driver
    url:jdbc:mysql://localhost:3306/mydb

2017.07.10

今日总结

今天学习了spring AOP的原理,静态代理和动态代理,动态代理又包括JDK代理和cglib代理。

明日计划

整合spring spring mvc mybatis,学会基本php操作,然后复习java,主要关注前端知识,java主要懂怎么封装数据就行了,然后前端框架获取数据,并进行展示。

5.spring对象的创建和获取原理

spring容器启动时,需要解析配置文件,配置文件按照逐行解析形式创建对象,根据Bean的Class属性,通过反射调用创建对象后注入在Spring容器内部。Spring内部通过map的形式存储已经生成的对象。map中的key就是bean的ID,map中的value就是创建好的对象。

7.Spring中获取对象的方式

  • 1.通过bean的ID获取对象
context.getBean("hello");--其中hello表示bean的ID
  • 2.通过class类型获取对象
context.getBean(Hello.class)--其中hello.class表示bean的class类型

虽然通过两种方式都能获取对象,但是建议大家使用id获取
如果xml配置了多个clas类型相同的bean就会报错

Spring 读取properties文件

  • 方式1.通过context:property-placeholder加载配置文件jdbc.properties中的内容
<context:property-placeholder location="classpath:jdbc.properties" ignore-unresolvable="true"/>
  • 方式2.使用注解的方式注入,主要用在java代码中使用注解注入properties文件中相应的value值
<bean id="prop" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
   <!-- 这里是PropertiesFactoryBean类,它也有个locations属性,也是接收一个数组,跟上面一样 -->
   <property name="locations">
       <array>
          <value>classpath:jdbc.properties</value>
       </array>
   </property>
</bean>
  •  方式3.使用util:properties标签进行暴露properties文件中的内容
<util:properties id="propertiesReader" location="classpath:jdbc.properties"/>
  • 方式4.自定义工具类PropertyUtil,并在该类的static静态代码块中读取properties文件内容保存在static属性中以供别的程序使用
public class PropertyUtil {
    private static final Logger logger = LoggerFactory.getLogger(PropertyUtil.class);
    private static Properties props;
    static{
        loadProps();
    }

    synchronized static private void loadProps(){
        logger.info("开始加载properties文件内容.......");
        props = new Properties();
        InputStream in = null;
        try {
       <!--第一种,通过类加载器进行获取properties文件流-->
            in = PropertyUtil.class.getClassLoader().getResourceAsStream("jdbc.properties");
        <!--第二种,通过类进行获取properties文件流-->
            //in = PropertyUtil.class.getResourceAsStream("/jdbc.properties");
            props.load(in);
        } catch (FileNotFoundException e) {
            logger.error("jdbc.properties文件未找到");
        } catch (IOException e) {
            logger.error("出现IOException");
        } finally {
            try {
                if(null != in) {
                    in.close();
                }
            } catch (IOException e) {
                logger.error("jdbc.properties文件流关闭出现异常");
            }
        }
        logger.info("加载properties文件内容完成...........");
        logger.info("properties文件内容:" + props);
    }

    public static String getProperty(String key){
        if(null == props) {
            loadProps();
        }
        return props.getProperty(key);
    }

    public static String getProperty(String key, String defaultValue) {
        if(null == props) {
            loadProps();
        }
        return props.getProperty(key, defaultValue);
    }
}

JSP九大内置对象及四个作用域

request 请求对象  类型 javax.servlet.ServletRequest 作用域 Request
response 响应对象 类型 javax.servlet.SrvletResponse 作用域 Page
pageContext 页面上下文对象 类型 javax.servlet.jsp.PageContext 作用域 Page
session 会话对象 类型 javax.servlet.http.HttpSession 作用域 Session
application 应用程序对象 类型 javax.servlet.ServletContext 作用域 Application
out 输出对象 类型 javax.servlet.jsp.JspWriter 作用域 Page
config 配置对象 类型 javax.servlet.ServletConfig 作用域 Page
page 页面对象 类型 javax.lang.Object 作用域 Page
exception 例外对象 类型 javax.lang.Throwable 作用域 page
“exception” 对象则代表了JSP文件运行时所产生的例外对象,此对象不能在一般JSP文件中直接使用,而只能在使用了“<%@ page isErrorPage="true "%>”的JSP文件中使用。
何为作用域
  先让我们看看效果:
  大概流程是这样的,我们访问index.jsp的时候,分别对pageContext, request, session,application四个作用域中的变量进行累加。(当然先判断这个变量是不是存在,如果变量不存在,则要把变量初始化成1)。计算完成后就从index.jsp执行forward跳转到test.jsp。在test.jsp里再进行一次累加,然后显示出这四个整数来。
  从显示的结果来看,我们可以直观的得出结论:
  page里的变量没法从index.jsp传递到test.jsp。只要页面跳转了,它们就不见了。
  request里的变量可以跨越forward前后的两页。但是只要刷新页面,它们就重新计算了。
  session和application里的变量一直在累加,开始还看不出区别,只要关闭浏览器,再次重启浏览器访问这页,session里的变量就重新计算了。
application里的变量一直在累加,除非你重启tomcat,否则它会一直变大。
作用域规定的是变量的有效期限
  如果把变量放到pageContext里,就说明它的作用域是page,它的有效范围只在当前jsp页面里。
  从把变量放到pageContext开始,到jsp页面结束,你都可以使用这个变量。
  如果把变量放到request里,就说明它的作用域是request,它的有效范围是当前请求周期。
  所谓请求周期,就是指从http请求发起,到服务器处理结束,返回响应的整个过程。在这个过程中可能使用forward的方式跳转了多个jsp页面,在这些页面里你都可以使用这个变量。
  如果把变量放到session里,就说明它的作用域是session,它的有效范围是当前会话。
  所谓当前会话,就是指从用户打开浏览器开始,到用户关闭浏览器这中间的过程。这个过程可能包含多个请求响应。也就是说,只要用户不关浏览器,服务器就有办法知道这些请求是一个人发起的,整个过程被称为一个会话(session),而放到会话中的变量,就可以在当前会话的所有请求里使用。
  如果把变量放到application里,就说明它的作用域是application,它的有效范围是整个应用。
  整个应用是指从应用启动,到应用结束。我们没有说“从服务器启动,到服务器关闭”,是因为一个服务器可能部署多个应用,当然你关闭了服务器,就会把上面所有的应用都关闭了。
  application作用域里的变量,它们的存活时间是最长的,如果不进行手工删除,它们就一直可以使用。
  与上述三个不同的是,application里的变量可以被所有用户共用。如果用户甲的操作修改了application中的变量,用户乙访问时得到的是修改后的值。这在其他scope中都是不会发生的,page, request,session都是完全隔离的,无论如何修改都不会影响其他人的数据。

2017.07.03

今天主要学习了spring框架,主要包括,spring导包,配置文件的编写,然后就是学习spring四种对象创建方式:

  • 默认构造方法创建对象(用的最多)
    Spring中默认创建对象的方式,就是通过无参构造创建对象。

  • 通过静态工厂创建对象
    静态工厂中,最为关键的部分就是静态方法,如果没有静态方法,那么必然报错。
    通过静态方法创建对象,和通过类名.static方法的方式一致

  • 实例工厂创建对象

  • Spring工厂创建对象
    public class SpringFactory implements FactoryBean

明日计划

留言板,已经完成了用户登录,留言,分页显示等功能,明天要做如下功能,注册,留言删除。留言的修改。然后就是继续学习spring框架。

Spring-MVC

SpringMVC是一个前端控制框架,将代替传统的Servlet服务。SpringMVC是Spring的一大组件。

Servlet的缺点

  • 一个servlet至少需要配置8行,大型servlet数量众多,xml会很繁琐。
<servlet>
    <servlet-name>AjaxServlet</servlet-name>
    <servlet-class>servlet.AjaxServlet</servlet-class>
  </servlet>
<servlet-mapping>
    <servlet-name>AjaxServlet</servlet-name>
    <url-pattern>/servlet/AjaxServlet</url-pattern>
  </servlet-mapping>
  • servlet获取用户传入的数据比较繁琐
String name = request.getParameter("name");
  • 服务端获取的都是String类型,需要手动转换类型
  • 对于一个操作,都需要写一个servlet
  • servlet的方法单一,只有doGet() doPost()

url的路径问题

url:localhost:8090/SpringMVC/addUserServlet
> 处理过程:servlet -- service(业务操作)--Dao(入库操作) = handel
url:localhost:8090/SpringMVC/hello.action //springmvc的路径

SpringMVC的组件

  • 前端控制器

只负责request,response对象的转发

  • 处理器映射器

将URL匹配对应的的Controller

  • 处理器适配器

执行对应的handel

  • 视图解析器

将页面的逻辑名称,转化为对应的具体页面路径

SpringMVC

  • 客户端发送request请求 localhost:8090/SpringMVC/hello.action
  • 请求处理器映射handler(找到匹配的controller类)
  • 返回能够处理的那个Controller类
  • 请求处理器适配器执行handler
  • 执行handler(Controller-servlet-dao)
  • 将处理结果返回,返回ModelAndView对象,model表示处理后的数据,view表示页面的逻辑名称
  • 将ModelAndView 对象,返还给前端控制器。
  • 请求视图解析器解析view对象(将页面逻辑名称拼接成一个完整的页面路径)
  • 将完整的页面路径再次返还给前端控制器
  • 将model数据填充到Request域中

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.