最重要的两个特性:IOC(控制反转 Inversion Of Control),AOP(面向切面编程)
学习资源传送门:
本文参考:how2j的相关教程
AOP DI IOC
Spring框架-耦合解耦-BeanFactory模式
spring笔记
spring探秘
主要用来降低程序间的耦合性.
在不用Sping框架时,我们为了解决程序间的耦合问题,即尽量减少使用new 来创建对象,可以利用工厂模式来减耦,通过将对象的创建全部交给工厂类,工厂类中的某个方法通过读取配置文件properties,将对象创建出来并且存入Map容器中,其他类需要使用到某个对象直接到容器中去取.降低耦合性的例子还有JDBC注册驱动类,两种方法,一个是DriverManager.registerDriver(new Driver()),另一个是class.forName("com.mysql.jdbc.driver")利用反射来注册,有效的降低了耦合性,Spring 基于此,利用IOC将对象创建的权力交给Spring,某个类需要哪个对象直接到Spring容器中去取即可,这也就是控制反转。
Dependency Inject,也就是依赖注入,容器在运行时直接将某个类需要用到的一些其他对象提供给他。
IOC:获得依赖对象的过程被反转。控制被反转之后,获得依赖对象的过程由自身管理变为了由IOC容器主动注入 解耦
它运用了一种设计模式----工厂模式,把创建对象的工作交给工厂去完成,在xml里配置好,运用反射机制,通过类名得到对象,当需要哪种对象时,Spring会自动帮我们生成。(从通过手动new 构造方法调用,变成了交由Spring创建对象)
标注 Bean 类 @Component("bean 的 id")//首字母小写的 Bean 类名
@Repository:在数据访问层(dao 层)使用
@Service:在业务逻辑层(service 层)使用
@Controller:在展现层(MVC→Spring MVC)使用
DI 依赖注入 Dependency Inject. IOC容器在运行期间,动态注入bean依赖关系
DI相关注解:@Autowired 自动装配 @Resource(name="指定 Bean 的 id")
使用注解配置 IoC 和 DI
applicationContext.xml是Spring的核心配置文件
//注入对象
测试TestSpring类
ApplicationContext context = new ClassPathXmlApplicationContext(new String[] { "applicationContext.xml" });
Product p = (Product) context.getBean("p");
System.out.println(p.getName());//product1
System.out.println(p.getCategory().getName());//category 1
注解配置
//注入对象
其一 @Autowired
属性 方法
其二 @Resource(name="c")
对Bean的注解
//扫描bean包
为Product 类 加上@Component注解,即表明此类是bean
@Component("p")
AOP是一种与语言无关的程序思想、编程范式。项目业务逻辑中,将通用的模块以水平切割的方式进行分离统一处理,常用于日志、权限控制、异常处理等业务中。
面向切面编程的思想里面,把功能分为核心业务功能,和周边功能。 所谓的核心业务,比如登陆,增加数据,删除数据都叫核心业务 所谓的周边功能,比如性能统计,日志,事务管理等等 周边功能在Spring的面向切面编程AOP思想里,即被定义为切面
在面向切面编程AOP的思想里面,核心业务功能和切面功能分别独立进行开发然后把切面功能和核心业务功能 "编织" 在一起,这就叫AOP
AOP思想就是把中间的非主流程的代码(比如:验证、事务管理、缓存、日志记录等), 横向抽取出来放在一个公共的类中, 也就是切面.可以通过Spring框架来配置该切面.
运用了动态代理和反射技术。反射用到两个重要的接口,invocationHandler接口和proxy接口。invocationHandler唯一一个方法invoke方法。
1. 功能分两大类,辅助功能和核心业务功能
2. 辅助功能和核心业务功能彼此独立进行开发
3. 比如登陆功能,即便是没有性能统计和日志输出,也可以正常运行
4. 如果有需要,就把"日志输出" 功能和 "登陆" 功能 编织在一起,这样登陆的时候,就可以看到日志输出了
5. 辅助功能,又叫做切面,这种能够选择性的,低耦合的把切面和核心业务功能结合在一起的编程思想,就叫做切面编程
AOP理解
实现方式
把XML方式配置AOP 改造为注解方式
@Component("s") 注解ProductService 业务类
@Aspect 注解表示这是一个切面
@Component 表示这是一个bean,由Spring进行管理
@Around(value = "execution(* com.demo.service.ProductService.*(..))")
表示对com.demo.service.ProductService 这个类中的所有方法进行切面操作
扫描包下注解。定位业务类和切面类
找到被注解了的切面类,进行切面配置
注解方式 junit测试
//注解方式用到了junit,所以需要:junit-4.12.jar和hamcrest-all-1.3.jar
// 让 JUnit 直接启动 Spring 容器,测试类运行在容器中 表示这是一个Spring的测试类
@RunWith(SpringJUnit4ClassRunner.class)
// 启动 Spring 容器时定位Spring配置文件,默认加载当前包下的 "当前类名-context.xml"
@ContextConfiguration("classpath:applicationContext.xml")
3. @Autowired给这个测试类装配Category对象
4. @Test测试逻辑,打印c对象的名称
事务管理
注意:表的类型是INNODB才支持
导jar包
事务配置:
注解配置
开启事务注解解析器,并指定使用的事务管理器 Bean 的 id(默认为 transactionManager):
方法上加事务注解
@Transactional(propagation=Propagation.REQUIRED,rollbackForClassName="Exception")
AOP实例
核心:
核心控制器:DispatcherServlet
请求解析器:HandlerMapping
结果解析器:ModelAndView
视图解析器:ViewResolver
整个工作流程:前台发送url请求,核心控制器接收到请求后调用请求解析器解析,通过映射找到对应的controller层,再调用service层,Dao层,最后返回结果,结果解析器进行装载和传输数据,最后核心控制器调用视图解析器解析视图匹配相应的页面然后跳转。
网上找的一个流程图如下,方便理解。
开启注解
在 mvc.xml 中开启 Spring MVC 注解的解析器,使用该标签后,会自动注册核心 Bean
----------------
项目步骤
创建dynamic web project
导jar包
在WEB-INF目录下创建 web.xml
配置Spring MVC的入口 DispatcherServlet,把所有的请求都提交到该Servlet
注意:springmvc
springmvc
org.springframework.web.servlet.DispatcherServlet
1
springmvc
/
处理器映射(HandlerMapping)
在WEB-INF目录下创建 springmvc-servlet.xml
建Spring MVC 的映射配置文件(xxx-servlet.xml),文件名的开头 与上面 web.xml 中的 元素配置的 servlet-name 内容对应
这是Spring MVC的 映射配置文件表示访问路径/index会交给id=indexController的bean处理
id=indexController的bean配置为类:IndexController
indexController
控制类 IndexController 实现接口Controller ,提供 方法handleRequest 处理请求
控制器最后一件事将模型数据打包,并且表示出用于渲染输出的视图名(逻辑视图名)。它接下来会将请求连同模型和视图名发送回 DispatcherServlet。
SpringMVC通过 ModelAndView 对象把模型和视图结合在一起
ModelAndView mav = new ModelAndView("index.jsp"); //表示视图是index.jsp
mav.addObject("message", "Hello Spring MVC"); //模型数据是 message,内容是 “Hello Spring MVC”
public class IndexController implements Controller {
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
ModelAndView mav = new ModelAndView("index.jsp");
mav.addObject("message", "Hello Spring MVC");
return mav;
}
}
DispatcherServlet 将会使用视图解析器(view resolver)来将逻辑视图名匹配为一个特定的视图实现
视图
在WebContent目录下创建index.jsp,通过EL表达式显示message的内容
1. 用户访问 /index 2. 根据web.xml中的配置 所有的访问都会经过DispatcherServlet
3. 根据 根据配置文件springmvc-servlet.xml ,访问路径/index会进入IndexController类
4. 在IndexController中指定跳转到页面index.jsp,并传递message数据5. 在index.jsp中显示message信息
---------------
-----
视图定位
视图解析器ViewResolver
负责定位视图,它接受一个由 DispaterServlet 传递过来的逻辑视图名来匹配一个特定的视图。
有一些页面我们不希望用户用户直接访问到,例如有重要数据的页面,例如有模型数据支撑的页面。
【WEB-INF】是 Java Web 中默认的安全目录,是不允许用户直接访问的(也就是你说你通过 localhost/WEB-INF/不能访问)
其作用是把视图约定在 /WEB-INF/page/*.jsp 这个位置 配置了一个 Spring MVC 内置的一个视图解析器,该解析器是遵循着一种约定:会在视图名上添加前缀和后缀,进而确定一个 Web 应用中视图资源的物理路径的。
把IndexController类的这一行代码 ModelAndView mav = new ModelAndView("index.jsp");
修改为 ModelAndView mav = new ModelAndView("index");
在WEB-INF下新建目录page把index.jsp移动到 WEB-INF/page 目录下 ----
-------
注解方式跳转
在IndexController类前面加上 @Controller 表示该类是一个控制器
在方法handleRequest 前面加上 @RequestMapping("/index") 表示路径/index会映射到该方法上
注意: 不再让 IndexController实现Controller接口
(@RequestMapping 作用在类上,那么就相当于是给该类所有配置的映射地址前加上了一个地址)
修改springmvc-servlet.xml 去掉映射相关的配置(bean),因为已经使用注解方式了
增加 组件扫描
-------
接收表单数据 模型传参
同名匹配
把方法定义的形参名字设置成和前台传入参数名一样的方法,来获取到数据(同名匹配规则)
使用 @RequestParam("前台参数名") 来注入
value:表示请求参数的参数名。 required:表示该参数是否必须,默认true。 defaultValue:请求参数的默认值。
自动装箱
回显数据:1.servlet原生API 2.用 Spring MVC 所提供的 ModelAndView 对象
3.用Model 对象(使用 @ModelAttribute 注解,首先调用 model() 方法)
-----
客户端跳转
不管是地址 /hello 跳转到 index.jsp 还是 /test 跳转到 test.jsp,
这些都是服务端的跳转,也就是 request.getRequestDispatcher("地址").forward(request, response);
@RequestMapping("/jump")
public ModelAndView jump() {
ModelAndView mav = new ModelAndView("redirect:/index");
return mav;
}
访问jump重定向至index 也可以用
@RequestMapping("/jump")
public String jump() {
return "redirect:/index";
}
------
session
Session在用户登录,一些特殊场合在页面间传递数据的时候会经常用到
刷新访问次数-- 修改IndexController :
映射 /check 到方法check()
为方法check()提供参数 HttpSession session ,这样就可以在方法体中使用session了
接下来的逻辑就是每次访问为session中的count+1.最后跳转到check.jsp页面
@RequestMapping("/check")
public ModelAndView check(HttpSession session) {
Integer i = (Integer) session.getAttribute("count");
if (i == null)
i = 0;
i++;
session.setAttribute("count", i);
ModelAndView mav = new ModelAndView("check");
return mav;
}
--------
中文问题 (form 设置method="post")
配置 Spring MVC 字符编码过滤器来完成,在 web.xml 中添加
CharacterEncodingFilter
org.springframework.web.filter.CharacterEncodingFilter
encoding
utf-8
CharacterEncodingFilter
/*
-----
JSON中文问题
加注解@ResponseBody 转为json
JSONObject.toJSON(cs).toString() 注:toString()方法内部还是调用了toJSONString()方法
var category={"name":name,"id":id};
var jsonData = JSON.stringify(category);
----
----
上传文件
使用基于Apache FileUpload上传组件实现文件的上传,步骤:
需要先导入 commons-io-1.3.2.jar 和 commons-fileupload-1.2.1.jar 两个包
配置上传解析器 编写jsp
编写控制器
@Controller
public class UploadController {
@RequestMapping("/upload")
public void upload(@RequestParam("picture") MultipartFile picture) throws Exception {
System.out.println(picture.getOriginalFilename());
}
@RequestMapping("/test")
public ModelAndView upload() {
return new ModelAndView("upload");
}
}
javaweb文件上传和下载
-----
上传jpg
在web.xml中新增加一段
default
*.jpg
表示允许访问*.jpg。配置springmvc的servlet的时候,使用的路径是"/",导致静态资源在默认情况下不能访问,所以要加上这一段,允许访问jpg。 并且必须加在springmvc的servlet之前。
配置spring-mvc使用的路径是/*.do,就不会有这个问题了。
配置springmvc-servlet.xml
新增加一段配置
开放对上传功能的支持
上传页面jsp,需要注意的是form 的两个属性必须提供method="post" 和 enctype="multipart/form-data" 缺一不可
上传组件 增加一个属性 accept="image/*" 表示只能选择图片进行上传
留意 image" accept="image/*" /> 这个image,后面会用到这个image
在UploadedImageFile中封装MultipartFile类型的字段 image ,用于接受页面的注入
这里的字段 image 必须和上传页面upload.jsp中的image image" accept="image/*" />保持一致
public class UploadedImageFile {
MultipartFile image;
public MultipartFile getImage() {
return image;
}
public void setImage(MultipartFile image) {
this.image = image;
}
}
新建 类UploadController 作为上传控制器
准备 方法upload 映射上传路径 /uploadImage
1. 方法的 第二个参数UploadedImageFile 中已经注入好了 image
2. 通过 RandomStringUtils.randomAlphanumeric(10); 获取一个随机文件名。 因为用户可能上传相同文件名的文件,为了不覆盖原来的文件,通过随机文件名的办法来规避
3. 根据request.getServletContext().getRealPath 获取到web目录下的image目录,用于存放上传后的文件。
4. 调用file.getImage().transferTo(newFile); 复制文件
5. 把生成的随机文件名提交给视图,用于后续的显示
@Controller
public class UploadController {
@RequestMapping("/uploadImage")
public ModelAndView upload(HttpServletRequest request, UploadedImageFile file)
throws IllegalStateException, IOException {
String name = RandomStringUtils.randomAlphanumeric(10);
String newFileName = name + ".jpg";
File newFile = new File(request.getServletContext().getRealPath("/image"), newFileName);
newFile.getParentFile().mkdirs(); //在父文件新建目录
file.getImage().transferTo(newFile); // 复制
ModelAndView mav = new ModelAndView("showUploadedFile");
mav.addObject("imageName", newFileName);
return mav;
}
}
显示
----
配置拦截器
拦截器类:IndexInterceptor preHandle(), 在访问Controller之前被调用 postHandle(), 在访问Controller之后,访问视图之前被调用 这里可以注入内容到modelAndView中,用于后续视图显示
afterCompletion(), 在访问视图之后被调用
获取参数值
1.Spring的功能 Spring架构最核心的功能就是依赖注入。DI 所有Spring模块的核心都是依赖注入。如果合理使用依赖注入,我们可以构建低耦合的应用,而且应用更容易进行单元测试。
减少重复代码 Spring提供了很多模块比如Spring JDBC,Spring MVC,Spring Test。这些功能可以自己实现,但是借助这些封装的模块就能减少代码量,代码越少bug就越少。 很好的集成其他框架 Spring架构从不解决已经被解决的问题,而且和这些解决问题的框架能够很好的集成。比如Hibernate。 2.Spring MVC的功能 Spring MVC提供了一种轻度耦合的方式来开发web应用。 Spring MVC是Spring的一个模块式一个web框架。通过Dispatcher Servlet, ModelAndView 和 View Resolver,开发web应用变得很容易。解决的问题领域是网站应用程序或者服务开发——URL路由、Session、模板引擎、静态Web资源等等。
持久层框架
ORM(Object/Relation Mapping):对象/关系数据库映射
1. 必须要有一个公共无参构造(写了带参构造必须添加一个,都不写则有默认)
2. Javabean类不应有公共属性,属性都应该是 private
3. 为私有(private声明)属性提供符合命名规范的get/set方法
4. 应该要实现序列化 serializeable 接口
5. javaBean类必须是一个公共类,将其访问属性设置为public
)
MyBatis 的常用 API
SqlSessionFactory SqlSession
用JDBC访问数据库,除了需要自己写SQL之外,还必须操作Connection, Statement, ResultSet 这些其实只是手段的辅助类。 不仅如此,访问不同的表,还会写很多雷同的代码
使用Mybatis只需要自己提供SQL语句,其他的工作,诸如建立连接,Statement, JDBC相关异常处理等等都交给Mybatis去做了,那些重复性的工作Mybatis也给做掉了
MyBatis 支持使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。
-------
步骤
创建实体类映射表
配置文件mybatis-config.xml
mybatis-config.xml配置 提供连接数据库用的驱动,数据库名称,编码方式,账号密码
或者 引入外部资源db.properties文件,配置接mysql数据库的一些基本信息
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/n_db
jdbc.username=root
jdbc.password=admin
在mybatis的配置文件中添加
别名,自动扫描目录pojo包下类型
映射Category.xml
配置文件Category.xml
-------
mybatis进阶
-------
URL定位资源,用HTTP动词(GET,POST,DELETE,DETC)描述操作。
URL HiddenHttpMethodFilter
HiddenHttpMethodFilter
org.springframework.web.filter.HiddenHttpMethodFilter
HiddenHttpMethodFilter
/*
/${c.id}
Controller类
@RequestMapping(value="/categories",method=RequestMethod.GET)
@RequestMapping(value="/categories/{id}",method=RequestMethod.PUT)
update
显示 name="_method" value="PUT">
---------
数据库驱动 jar 包及数据源 druid 所需 jar 包
------
RBAC(Role-Based Access Control),基于角色的访问控制
------
应用分层
分层领域模型
----------
SSM框架的配置文件:
spring+springmvc+mybatis框架中用到了三个XML配置文件:web.xml,spring-mvc.xml,spring-mybatis.xml.
第一个不用说,每个web项目都会有的也是关联整个项目的配置.第二个文件spring-mvc.xml是springmvc的一些相关配置,第三个是mybatis的相关配置.
项目中还会用到两个资源属性文件jdbc.properties和log4j.properties.一个是关于jdbc 的配置,提取出来方便修改.另一个是日志文件的配置.
web.xml
1.监听器
2.spring配置文件路径
3.编码过滤器
4.spring mvc核心控制器DispatcherServlet
5.错误页面,异常页面
spring-mvc.xml
1.配置映射器与适配器
2.视图解析器
3.扫描包下@controller注解的类是控制器
spring-mybatis.xml.
1. 配置 //自动扫描包组件,将标注Spring注解的类自动转化Bean,同时完成Bean的注入
2 .加载数据源属性文件
3 .配置数据源
4. 配置sessionfactory
5. 装配Dao接口
6 .声明式事务管理
7 .注解事务切面
---------------
作为学习阶段的笔记,排版不太好,见谅。如有错误,恳请指出。