一、什么是Spring框架?Spring框架有哪些主要模块?
Spring框架是一个为Java应用程序的开发提供了综合、广泛的基础性支持的Java平台。Spring帮助开发者解决了开发中基础性的问题,使得开发人员可以专注于应用程序的开发。Spring框架本身亦是按照设计模式精心打造,这使得我们可以在开发环境中安心的集成Spring框架,不必担心Spring是如何在后台进行工作的。
Spring框架至今已集成了20多个模块。这些模块主要被分如下图所示的核心容器、数据访问/集成,、Web、AOP(面向切面编程)、工具、消息和测试模块。
Spring既是一个AOP框架,也是一IOC容器。 :Spring AOP,Spring DAO,Spring ORM,Spring Web,Spring Context, Spring Web MVC。
依赖注入:
用接口编程,在程序中不出现new关键字,而是用接口来命名引用,然后通过某种方式把接口的某个实现类的实例注入到引用里,从而实现接口与具体实现类的松耦合。
依赖于接口,不依赖于具体类
控制反转:
容器控制程序之间的关系(通过XML配置),而非传统实现中的由程序代码直接操控 控制权由应用代码中转到了外部容器,控制权的转移,是所谓的反转。
AOP
方式很类似filter,就是在程序正常的业务流中间像切面一样插入很多其他需要执行的代码,比如登录时候,在进入登录页面前写入日志
它允许程序员对横切关注点或横切典型的职责分界线的行为(例如日志和事务管理)进行模块化。AOP 的核心构造是方面,它将那些影响多个类的行为封装到可重用的模块中。
AOP Advice(AOP通知)分为:
前置通知 后置通知 异常通知 环绕通知
spring使用AOP来支持声明式事务,会根据事务属性,自动在方法调用之前决定是否开启一个事务,并在方法执行之后决定事务提交或回滚事务
二,如何在web应用里面配置spring?
在web.xml中加入如下同容,在启动web服务器时加载/WEB-INF/applicationContext.xml中的内容。
context,
org.springframework.web.context.ContextLoaderServlet
缺省情况下, 它会在WEB-INF/applicationContext.xml文件找Spring的配置。 你可以通过定义一个元素名字为”contextConfigLocation”来改变Spring配置文件的位置。示例如下:
三,如何在spring中实现国际化?
在applicationContext.xml加载一个bean
message
在src目录下建多个properties文件
四,Spring框架中Bean的生命周期
1、Bean的定义
Spring通常通过配置文件定义Bean。如:
2,初始化
1、在配置文档中通过指定init-method 属性来完成
2, Bean实现InitializingBean接口,并且增加 afterPropertiesSet() 方法。自动调用afterPropertiesSet()方法对Bean进行初始化。
3,Bean的调用
有三种方式可以得到Bean并进行调用
2、使用BeanFactory
3、使用ApplicationConttext
4、Bean的销毁
1、使用配置文件中的 destory-method 属性
1、使用配置文件中的 destory-method 属性
与初始化属性 init-methods类似
2、实现 org.springframwork.bean.factory.DisposebleBean接口,与InitializingBean接口类似
如果实现了DisposebleBean接口
在Spring中,AOP代理可以是JDK动态代理或者CGLIB代理cv
==》AOP和Filter的区别
1、拦截器是基于java的反射机制的,而过滤器是基于函数回调
2、过滤器依赖与servlet容器,而拦截器不依赖与servlet容器
3、拦截器只能对action请求起作用(因为不依赖容器,可多次调用),而过滤器则可以对几乎所有的请求起作用(依赖容器,只调用一次)
2、过滤器依赖与servlet容器,而拦截器不依赖与servlet容器
3、拦截器只能对action请求起作用(因为不依赖容器,可多次调用),而过滤器则可以对几乎所有的请求起作用(依赖容器,只调用一次)
4、拦截器可以访问action上下文、值栈里的对象,而过滤器不能
过滤器 访问特定资源(Web 页、JSP 页、servlet)时的身份认证
实现javax.servlet.Filter 接口
init(FilterConfig):这是容器所调用的初始化方法。它保证了在第一次 doFilter() 调用前由容器调用。它能获取在 web.xml 文件中指定的filter初始化参数。
doFilter(ServletRequest, ServletResponse, FilterChain):这是一个完成过滤行为的方法。它同样是上一个过滤器调用的方法。引入的 FilterChain 对象提供了后续过滤器所要调用的信息。
destroy():容器在销毁过滤器实例前,doFilter()中的所有活动都被该实例终止后,调用该方法。
Filter链介绍
所有过滤器都服从调用的过滤器链,并通过定义明确的接口得到执行。WebApplication可以指定许多过滤器来完成相关的工作.那么它们就组成一个过滤器链来完成相应的工作
<filter-name >encoding</ 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 >encoding</ filter-name>
<url-pattern >/*</ url-pattern>
</filter-mapping >
<filter-name >shiroFilter</ filter-name>
//DelegatingFilterProxy 表示一个代理过滤器,交给beanid=shiroFilter来过滤,别的过滤器是指定java类
<filter-class> org.springframework.web.filter.DelegatingFilterProxy</filter-class >
</filter >
<filter-mapping >
<filter-name >shiroFilter</ filter-name>
<url-pattern >*.do</ url-pattern>
</filter-mapping >
<filter >
<filter-name >loginFilter</ filter-name>
<filter-class >com.oa.commons.filter.LoginFilter</ filter-class>
</filter >
<filter-mapping >
<filter-name >loginFilter</ filter-name>
<url-pattern >*.do</ url-pattern>
</filter-mapping >
<bean id ="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean" >
<property name ="securityManager" ref="securityManager" />
<property name ="loginUrl" value="/login_timeout.jsp" />
<property name ="filters" >
<map>
<entry key ="isLogin" value-ref="myUserAuthFilter" />
</map>
</property>
<property name ="filterChainDefinitions" >
<value>
==》安全框架Shiro:
UserRealm 继承 AuthorizingRealm 显然是为了获取权限信息,对用户进行访问控制;继承AuthenticatingRealm显然是为了获得用户的认证信息,对用户进行认证
Map<String,Collection<String>> map=userService.selectRolesPowers(userId);
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
info.addRoles(map.get( "roleIds"));
info.addStringPermissions(map.get( "powers"));
return info;
查询一次后对用户权限缓存。用户退出登录时清这个缓存。所以配置完权限要重新登录。
使用:开启权限注解和权限JSP标签。达到对url xxx.do方法的控制。方法内部,还可以调用API来判断权限/角色。
1,登录的加密
RSA加密
登录先申请公钥,后台算法。公钥的模数和指数
//生成公钥的模数和指数
String pwd=UUID.randomUUID().toString();
session.setAttribute( "jmpw", pwd);//密码种子存到session
RSAPublicKeyModel publicKey = RSAUtils.getPublicKeyModel(pwd );
2,然后JS用RSA加密,传给后台
var key = RSAUtils.getKeyPair(data.exponent, '', data.modulus);
3,后台再解密,
//解密使用默认的私钥解密由JS加密(使用此类提供的公钥加密)的字符串。
String ps =(String)request.getSession().getAttribute("jmpw");
String pwd=RSAUtils. decryptStringByJs(ps ,password);
验证系统防火墙,例:ip,时间 等访问限制,先排除开发人员,超级管理员
验证用户是否被限制登陆
4,取MD5值,和数据库MD5对比通过,再使用shiro登录
Subject currentUser =SecurityUtils.getSubject();
UsernamePasswordToken token =new UsernamePasswordToken(u.getId(), password);
currentUser.login( token);//登录认证 记录登陆信息
5,最后用户访问时,按照这个token来验证是否登录了。
==》 JS插件写法
减少全局变量冲突,先定义一个“类”,再写方法。
真有冲突时,改下类名搞定。
//定义RSAUtils对象,闭包,内部var是不可访问的。要访问用RSAUtils.getKeyPair
(function($w) {
if(typeof $w.RSAUtils === 'undefined')
var RSAUtils = $w.RSAUtils = {} ;
var RSAKeyPair = function (encryptionExponent, decryptionExponent, modulus) {
var $dmath = RSAUtils;
this.e = $dmath.biFromHex(encryptionExponent);
this.d = $dmath.biFromHex(decryptionExponent);
this.m = $dmath.biFromHex(modulus);
// We can do two bytes per digit, so
// chunkSize = 2 * (number of digits in modulus - 1).
// Since biHighIndex returns the high index, not the number of digits, 1 has
// already been subtracted.
this.chunkSize = 2 * $dmath.biHighIndex(this .m);
this.radix = 16;
this.barrett = new $w.BarrettMu(this.m);
};
RSAUtils.getKeyPair = function(encryptionExponent, decryptionExponent, modulus) {
return new RSAKeyPair(encryptionExponent, decryptionExponent, modulus);
};
} )(window);
调用,使用RSAUtils对象来做。
var key = RSAUtils.getKeyPair(data.exponent, '', data.modulus);
结论:有权访问另一个函数作用域内变量的函数都是闭包。对于后台来说,等同于面向对象。
就是函数的嵌套,内层的函数可以使用外层函数的所有变量
定义完函数,执行一遍。就有了对象存在。
if (typeof JSON !== 'object') {
JSON = {};
}
(function () {
} ());
APP自己写的BaseFty BaseCtrl
==》最后写JS插件要注意内存泄露,不要循环引用