java框架 spring+springmvc+mybatis 及ssm整合

Spring

最重要的两个特性:IOC(控制反转 Inversion Of Control),AOP(面向切面编程)

  • 对于 Spring 框架而言,一切 Java 对象都是 Bean
  • Spring 的 IoC 容器降低了业务对象替换的复杂性,组件之间解耦
  • Spring 的 AOP 支持允许将一些通用任务如安全、事务、日志等进行集中式处理,从而提供了更好的复用

学习资源传送门:

本文参考:how2j的相关教程

AOP DI IOC

Spring框架-耦合解耦-BeanFactory模式

spring笔记

spring探秘

Spring IOC

主要用来降低程序间的耦合性.

在不用Sping框架时,我们为了解决程序间的耦合问题,即尽量减少使用new 来创建对象,可以利用工厂模式来减耦,通过将对象的创建全部交给工厂类,工厂类中的某个方法通过读取配置文件properties,将对象创建出来并且存入Map容器中,其他类需要使用到某个对象直接到容器中去取.降低耦合性的例子还有JDBC注册驱动类,两种方法,一个是DriverManager.registerDriver(new Driver()),另一个是class.forName("com.mysql.jdbc.driver")利用反射来注册,有效的降低了耦合性,Spring 基于此,利用IOC将对象创建的权力交给Spring,某个类需要哪个对象直接到Spring容器中去取即可,这也就是控制反转。

 

 Spring DI

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

  • Spring 通过使用 Bean 后处理器(BeanPostProcessor)增加对注解的支持
  • 启动包扫描功能,以注册在指定包下带有 IoC 和 DI 相关注解的 Bean:
  • 启用 4 个 Bean 后处理器(当启动了包扫描功能后,在 Spring 测试环境中可以省略):

applicationContext.xml是Spring的核心配置文件

<bean name="c" class="com.how2java.pojo.Category">  
    <property name="name" value="category 1" />    
</bean> 
<bean name="p" class="com.how2java.pojo.Product">    
    <property name="name" value="product1" />      
    <property name="category" ref="c" />  //注入对象
 </bean>

测试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

注解配置

//注入对象
<context:annotation-config/>

<!--   <property name="category" ref="c" /> -->
其一  @Autowired
属性 方法
其二  @Resource(name="c")

Bean的注解

//扫描bean包
<context:component-scan base-package="com.ex.pojo"/>

 为Product 类 加上@Component注解,即表明此类是bean
 @Component("p")
			

AOP

    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 这个类中的所有方法进行切面操作

<context:component-scan base-package="com.how2java.aspect"/>
<context:component-scan base-package="com.how2java.service"/>
 扫描包下注解。定位业务类和切面类
<aop:aspectj-autoproxy/>  
 找到被注解了的切面类,进行切面配置

注解方式 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):

<tx:annotation-driven transaction-manager="transactionManager"/>
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>

方法上加事务注解 

@Transactional(propagation=Propagation.REQUIRED,rollbackForClassName="Exception")

AOP实例


Spring MVC

  • 在 Spring MVC 框架中,控制器实际上由两个部分共同组成,即拦截所有用户请求和处理请求的通用代码都由前端控制器 DispatcherServlet完成,
  • 而实际的业务控制(诸如调用后台业务逻辑代码,返回处理结果等)则由 Controller 处理

核心:

核心控制器:DispatcherServlet

请求解析器:HandlerMapping

结果解析器:ModelAndView

视图解析器:ViewResolver

整个工作流程:前台发送url请求,核心控制器接收到请求后调用请求解析器解析,通过映射找到对应的controller层,再调用service层,Dao层,最后返回结果,结果解析器进行装载和传输数据,最后核心控制器调用视图解析器解析视图匹配相应的页面然后跳转。

网上找的一个流程图如下,方便理解。

常用 API

  • Controller 接口ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response)
  • Mode 接口,模型数据的存储容器,类似 Map 接口Model addAttribute(String attributeName, Object attributeValue):// 添加模型数据
  • ModelAndView 类ModelAndView addObject(String attributeName, Object attributeValue): 添加模型数据void setViewName(String viewName):设置逻辑视图名,视图解析器会根据该名字解析到具体的视图页面

开启注解

在 mvc.xml 中开启 Spring MVC 注解的解析器,使用该标签后,会自动注册核心 Bean

----------------

项目步骤

创建dynamic web project

导jar包

在WEB-INF目录下创建 web.xml

配置Spring MVC的入口 DispatcherServlet,把所有的请求都提交到该Servlet

注意:springmvc

<servlet>
		<servlet-name>springmvc</servlet-name>
		<servlet-class>
			org.springframework.web.servlet.DispatcherServlet
		</servlet-class>
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>springmvc</servlet-name>
		<url-pattern>/</url-pattern>
	</servlet-mapping>

处理器映射(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

<bean id="simpleUrlHandlerMapping"
		class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
		<property name="mappings">
			<props>
    			<!-- /index 路径的请求交给 id 为 indexController 的控制器处理-->
				<prop key="/index">indexController</prop>
			</props>
		</property>
</bean>
<bean id="indexController" class="controller.IndexController"></bean>

控制器

控制类 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的内容

<h1>${message}</h1>

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/不能访问)

<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
   <property name="prefix" value="/WEB-INF/page/" />
   <property name="suffix" value=".jsp" />
</bean>

其作用是把视图约定在 /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 中添加

    <filter>  
        <filter-name>CharacterEncodingFilter</filter-name>  
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>  
        <init-param>  
            <param-name>encoding</param-name>  
            <param-value>utf-8</param-value>  
        </init-param>  
    </filter>  
    <filter-mapping>  
        <filter-name>CharacterEncodingFilter</filter-name>  
        <url-pattern>/*</url-pattern>  
    </filter-mapping>  	

-----

JSON中文问题

  <mvc:annotation-driven >
	   <mvc:message-converters register-defaults="true">
	      <bean class="org.springframework.http.converter.StringHttpMessageConverter">
	         <property name="supportedMediaTypes" value="text/plain;charset=UTF-8" />
	      </bean>
	   </mvc:message-converters>    
    </mvc:annotation-driven>

加注解@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中新增加一段

<servlet-mapping>
	    <servlet-name>default</servlet-name>
	    <url-pattern>*.jpg</url-pattern>
</servlet-mapping>

表示允许访问*.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

<form action="uploadImage" method="post" enctype="multipart/form-data">
  选择图片:<input type="file" name="image" accept="image/*" /> <br> 
  <input type="submit" value="上传">
</form>

在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;
	}
}

显示<img src="image/${imageName}"/>

----

拦截器

  • 自定义拦截器实现 HandlerInterceptorAdapter 接口
  • 重写拦截方法
  • 配置

配置拦截器

<mvc:interceptors>    
	    <mvc:interceptor>
         <!--拦截路径  /* 只能拦截一级路径;/** 可以拦截一级或多级路径 -->
	        <mvc:mapping path="/**"/>  
	        <!-- 定义在mvc:interceptor下面的表示是对特定的请求才进行拦截的 -->  
	        <bean class="interceptor.IndexInterceptor"/>      
	    </mvc:interceptor>  
	    <!-- 当设置多个拦截器时,先按顺序调用preHandle方法,然后逆序调用每个拦截器的postHandle和afterCompletion方法 -->  
	</mvc:interceptors> 

拦截器类:IndexInterceptor preHandle(), 在访问Controller之前被调用 postHandle(), 在访问Controller之后,访问视图之前被调用 这里可以注入内容到modelAndView中,用于后续视图显示

afterCompletion(), 在访问视图之后被调用

 

获取参数值


Spring和Spring MVC的区别

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资源等等。


MyBatis

持久层框架

ORM(Object/Relation Mapping):对象/关系数据库映射

  • 作用:把对持久化对象的保存、修改、删除等操作,转换成对数据库的操作
  • 映射关系:数据表映射类数据表的行映射对象(即实例)数据表的列(字段)映射对象的属性
  • 注意:实体类需符合 JavaBean 规范

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配置 提供连接数据库用的驱动,数据库名称,编码方式,账号密码

<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/how2java?characterEncoding=UTF-8"/>
<property name="username" value="root"/>
<property name="password" value="admin"/>	 

或者 引入外部资源db.properties文件,配置接mysql数据库的一些基本信息

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/n_db
jdbc.username=root
jdbc.password=admin

在mybatis的配置文件中添加

<properties resource="db.properties"></properties>

别名,自动扫描目录pojo包下类型

映射Category.xml

配置文件Category.xml

-------

mybatis进阶

-------

RESTful

URL定位资源,用HTTP动词(GET,POST,DELETE,DETC)描述操作。

URL HiddenHttpMethodFilter

<filter>
	   <filter-name>HiddenHttpMethodFilter</filter-name>
	   <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
	   <filter-name>HiddenHttpMethodFilter</filter-name>
	   <url-pattern>/*</url-pattern>
</filter-mapping>

/${c.id}

Controller类

@RequestMapping(value="/categories",method=RequestMethod.GET)

 

@RequestMapping(value="/categories/{id}",method=RequestMethod.PUT)

update

显示  name="_method" value="PUT"> 

---------

连接池

数据库驱动 jar 包及数据源 druid 所需 jar 包

<!-- 数据库连接池  druid -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
    <!-- 基本属性 url、user、password -->
    <property name="url" value="jdbc:mysql://localhost:3306/student?characterEncoding=UTF-8" />
    <property name="username" value="root" />
    <property name="password" value="admin" />
    <property name="driverClassName" value="com.mysql.jdbc.Driver" />

    <!-- 配置初始化大小、最小、最大 -->
    <property name="initialSize" value="3" />
    <property name="minIdle" value="3" />
    <property name="maxActive" value="20" />

    <!-- 配置获取连接等待超时的时间 -->
    <property name="maxWait" value="60000" />

    <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
    <property name="timeBetweenEvictionRunsMillis" value="60000" />

    <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
    <property name="minEvictableIdleTimeMillis" value="300000" />

    <property name="validationQuery" value="SELECT 1" />
    <property name="testWhileIdle" value="true" />
    <property name="testOnBorrow" value="false" />
    <property name="testOnReturn" value="false" />

    <!-- 打开PSCache,并且指定每个连接上PSCache的大小 -->
    <property name="poolPreparedStatements" value="true" />
    <property name="maxPoolPreparedStatementPerConnectionSize" value="20" />
</bean>

------

RBAC(Role-Based Access Control),基于角色的访问控制

  • 把许可权(Permission)与角色(Role)联系在一起,用户(User)通过充当合适角色的成员而获得该角色的许可权
  • 通过设计 @RequiredPermission 注解,贴在 Controller 中需要权限才能访问的请求方法上

------

应用分层

分层领域模型

  • DO(Data Object):与数据库表结构一一对应,通过 DAO 层向上传输数据源对象
  • DTO(Data Transfer Object):数据传输对象,Service 和 Manager 向外传输的对象
  • BO(Business Object):业务对象,可以由 Service 层输出的封装业务逻辑的对象
  • QUERY:数据查询对象,各层接收上层的查询请求
  • VO(View Object):显示层对象,通常是 Web 向模板渲染引擎层传输的对象

----------

SSM

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 .注解事务切面

---------------

作为学习阶段的笔记,排版不太好,见谅。如有错误,恳请指出。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd "> <!-- 自动扫描 --> <context:component-scan base-package="com.flong.*" /> <!-- 引入配置文件 --> <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="location" value="classpath:jdbc.properties" /> </bean> <!-- <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" lazy-init="false"> <property name="driverClassName" value="${jdbc.driver}" /> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> 初始化连接大小 <property name="initialSize" value="${jdbc.initialSize}"></property> 连接池最大数量 <property name="maxActive" value="${jdbc.maxActive}"></property> 连接池最大空闲 <property name="maxIdle" value="${jdbc.maxIdle}"></property> 连接池最小空闲 <property name="minIdle" value="${jdbc.minIdle}"></property> 获取连接最大等待时间 <property name="maxWait" value="${jdbc.maxWait}"></property> </bean> --> <bean id="dbPasswordCallback" class="com.flong.utils.DBPasswordCallback"> <description>数据库连接回调密码解密</description> </bean> <bean id="statFilter" class="com.alibaba.druid.filter.stat.StatFilter" lazy-init="true"> <description>状态过滤器</description> <property name="logSlowSql" value="true" /> <property name="mergeSql" value="true" /> </bean> <!-- 操作数据库删除,修改,添加的数据源 --> <bean id="writeDataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close" init-method="init" lazy-init="true"> <property name="driverClassName" value="${jdbc.driver}" /> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> <!-- 初始化连接大小 --> <property name="initialSize" value="${jdbc.initialSize}" /> <!-- 连接池最大数量 --> <property name="maxActive" value="${jdbc.maxActive}" /> <!-- 连接池最小空闲 --> <property name="minIdle" value="${jdbc.minIdle}" /> <!-- 获取连接最大等待时间 --> <property name="maxWait" value="${jdbc.maxWait}" /> <!-- --> <property name="defaultReadOnly" value="true" /> <property name="proxyFilters"> <list> <ref bean="statFilter" /> </list> </property> <property name="filters" value="${druid.filters}" /> <property name="connectionProperties" value="password=${password}" /> <property name="passwordCallback" ref="dbPasswordCallback" /> <property name="testWhileIdle" value="true" /> <property name="testOnBorrow" value="false" /> <property name="testOnReturn" value="false" /> <property name="validationQuery" value="SELECT 'x'" /> <property name="timeBetweenLogStatsMillis" value="60000" /> <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 --> <property name="minEvictableIdleTimeMillis" value="${minEvictableIdleTimeMillis}" /> <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 --> <property name="timeBetweenEvictionRunsMillis" value="${timeBetweenEvictionRunsMillis}" /> </bean> <!-- 操作数据库读的数据源 --> <bean id="readDataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close" init-method="init" lazy-init="true"> <property name="driverClassName" value="${jdbc.driver}" /> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> <!-- 初始化连接大小 --> <property name="initialSize" value="${jdbc.initialSize}" /> <!-- 连接池最大数量 --> <property name="maxActive" value="${jdbc.maxActive}" /> <!-- 连接池最小空闲 --> <property name="minIdle" value="${jdbc.minIdle}" /> <!-- 获取连接最大等待时间 --> <property name="maxWait" value="${jdbc.maxWait}" /> <!-- --> <property name="defaultReadOnly" value="true" /> <property name="proxyFilters"> <list> <ref bean="statFilter" /> </list> </property> <property name="filters" value="${druid.filters}" /> <property name="connectionProperties" value="password=${password}" /> <property name="passwordCallback" ref="dbPasswordCallback" /> <property name="testWhileIdle" value="true" /> <property name="testOnBorrow" value="false" /> <property name="testOnReturn" value="false" /> <property name="validationQuery" value="SELECT 'x'" /> <property name="timeBetweenLogStatsMillis" value="60000" /> <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 --> <property name="minEvictableIdleTimeMillis" value="${minEvictableIdleTimeMillis}" /> <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 --> <property name="timeBetweenEvictionRunsMillis" value="${timeBetweenEvictionRunsMillis}" /> </bean> <!--利用AbstractRoutingDataSource实现动态数据源切换 --> <bean id="dataSource" class="com.flong.utils.persistence.DynamicChooseDataSource" lazy-init="true"> <description>数据源</description> <property name="targetDataSources"> <map key-type="java.lang.String" value-type="javax.sql.DataSource"> <!-- write --> <entry key="write" value-ref="writeDataSource" /> <!-- read --> <entry key="read" value-ref="readDataSource" /> </map> </property> <!-- 从org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource这个类里面可以看到 defaultTargetDataSource这个对象,根据自己需求的情况默认的情况给一个默认的数据源. --> <property name="defaultTargetDataSource" ref="writeDataSource" /> <property name="methodType"> <map key-type="java.lang.String"> <!-- read --> <entry key="read" value=",get,select,count,list,query" /> <!-- write --> <entry key="write" value=",add,insert,create,update,delete,remove," /> </map> </property> </bean> <!-- springMyBatis完美整合,不需要mybatis的配置映射文件 --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <!-- 添加 mybatis-config配置上去。--> <property name="configLocation" value="classpath:mybatis-config.xml" /> <!-- 扫描com.flong.pojo下面的所有类,减少mybatis的mapping所有实体类的路径(parameterType),直接写一个JavaBean即可 --> <property name="typeAliasesPackage" value="com.flong.pojo"/> <!-- 自动扫描mapping.xml文件 --> <property name="mapperLocations" value="classpath:mapping/*.xml"></property> </bean> <!-- DAO接口所在包名,Spring会自动查找其下的类 --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.flong.dao" /> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property> </bean> <!-- (事务管理)transaction manager, use JtaTransactionManager for global tx --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> </bean> <!-- 配置事务通知属性 --> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <!-- 定义事务传播属性 --> <tx:attributes> <tx:method name="insert*" propagation="REQUIRED" /> <tx:method name="update*" propagation="REQUIRED" /> <tx:method name="edit*" propagation="REQUIRED" /> <tx:method name="save*" propagation="REQUIRED" /> <tx:method name="add*" propagation="REQUIRED" /> <tx:method name="new*" propagation="REQUIRED" /> <tx:method name="set*" propagation="REQUIRED" /> <tx:method name="remove*" propagation="REQUIRED" /> <tx:method name="delete*" propagation="REQUIRED" /> <tx:method name="change*" propagation="REQUIRED" /> <tx:method name="get*" propagation="REQUIRED" read-only="true" /> <tx:method name="find*" propagation="REQUIRED" read-only="true" /> <tx:method name="load*" propagation="REQUIRED" read-only="true" /> <tx:method name="*" propagation="REQUIRED" read-only="true" /> </tx:attributes> </tx:advice> <!-- 配置事务切面 --> <aop:config> <aop:pointcut id="serviceOperation" expression="execution(* com.flong.service.*.*(..))" /> <aop:advisor advice-ref="txAdvice" pointcut-ref="serviceOperation" /> </aop:config> </beans>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值