目录
2.3 构造方式注入:待补充 有很多参数不懂什么意思以及咱项目的配置
2.2 动态代理实现aop (目前只懂原理,缺少实际项目运用)
2.3 基于注解实现aop (目前只懂原理,缺少实际项目运用)
Spring框架_引人jar
Spring框架_控制反转(IOC)
- 如何使用IOC去注入Java对象
1.入门案例
1.1 目标类简介
- XML头配置
- UserService:业务层
- UserDao:Dao层
- UserDaoImpl:Dao实现层
- User:module层
1.2 XML头配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
</beans>
1.3 UserService:业务层
public class UserService {
private UserDAO userDAO ;
public UserDAO getUserDAO() {
return userDAO;
}
public void setUserDAO(UserDAO userDAO) {
this.userDAO = userDAO;
}
public void add(User user) {
userDAO.save(user); //业务逻辑,保存用户
}
}
1.4 UserDao:Dao层
package spring.DAO;
import spring.model.User;
public interface UserDAO {
//纯跨数据库平台的抽象接口:负责将user传递到数据库里
public void save(User user);//存数据的方法 不同的数据库其Save方法一定不同,故让其子类UserDAOImpl来根据实际情况实现数据传输
}
1.5 UserDaoImpl:Dao实现层
//具体实现了某种数据库连接
public class UserDAOImpl implements UserDAO{
public void save(User user) {
System.out.println("user saved!");
}
}
2.基于XML注入bean
2.1 Setter方式注入
- xml配置
<bean id="u" class="spring.DAO.implement.UserDAOImpl">
</bean>
<bean id="userService" class="spring.service.UserService" scope="prototype">
<!--scope默认singleton:每次调用同一个 UserDAOImpl对象 -->
<property name="userDAO" ref="u" />
<!--scope=prototype:每次实例化一个新的 UserDAOImpl对象 -->
</bean>
- 实现代码
ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");//new个bean工厂
UserService service = (UserService)ctx.getBean("userService");//通过注入方式创建DaoImpl对象
User u = new User();
service.add(u);
- 原理
首先从bean工厂拿到 id="userService" 的类UserService 对象,并且通过setter的方式注入了UserService 对象的属性 UserDao :UserDaoImpl对象,在调用service.add() 方法时,实际调用了 UserDaoImpl 的 save()方法
2.2 简单属性注入
- 常用于配置jdbc连接池 通过配置文件给连接池注入一些基本类型的值
- xml配置
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="${driver}" /> <property name="url" value="${url}" /> <property name="username" value="${user}" /> <property name="password" value="${password}" /> <!-- 数据库连接池配置 --> <property name="initialSize" value="10" /><!-- 初始化连接数量 --> <property name="maxActive" value="40" /><!-- 最大连接数量 --> <property name="maxIdle" value="0" /><!-- 最大空闲连接数量 --> <property name="minIdle" value="0" /><!-- 最小空闲连接数量 --> <property name="maxWait" value="2000" /> <property name="validationQuery" value="select 1" /> <property name="testOnBorrow" value="true" /> <property name="testOnReturn" value="false" /> </bean>
- 实现原理:等同于setter注入属性,只不过属性由java类变成了基本类型
2.3 构造方式注入:待补充 有很多参数不懂什么意思以及咱项目的配置
- xml配置
<bean id="u" class="spring.DAO.implement.UserDAOImpl">
</bean>
<bean id="userService" class="spring.service.UserService" scope="prototype">
<constructor-arg>
<ref bean="u"/>
</constructor-arg>
</bean>
2.4 扩展
- 自动装配 :autowire="byName" autowire="byType" :如果是接口,会自动装配其子类
<bean id="userService" class="spring.service.UserService" autowire="byName">
-
指定bean初始化时调用的方法,实例化对象结束时调用的方法 待补充:有什么用
<bean id="userService" class="spring.service.UserService" init-method="init" destroy-method="destroy" >
3.基于注解的方式注入
3.1 xml配置
<?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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
">
<!-- 扫描指定package -->
<context:component-scan base-package="com.chinasoft.imssreport" />
<!-- 扫描所有 -->
<context:annotation-config/>
</beans>
3.2 常用注解
- 注解:就是一个类,使用@注解名称
- 可以写在类名上 set方法上 属性上
生成bean的注解 @Component @Repository @Service @Controller
- @Component
@Component取代<bean class="">
@Component("id") 取代 <bean id="" class="">
- @Component注解衍生注解(功能一样)
@Repository :dao层
@Service:service层
@Controller:web层
注入bean的注解 @Autowired @Resource
- 按类型装配
- @Autowired :(默认bytype)
)
- 按名称装配
-
@Autowired @Qualifier("名称")
@Resource(name="名称")
- 生命周期
初始化:@PostConstruct
销毁:@PreDestroy
- 作用域
@Scope("prototype") 多例
Spring框架_面向切片(AOP)
1. 什么是aop
aop: 面向切片技术 用于弥补Java 只能纵向扩展 不能横向扩展的弱势 ,将一些通用业务逻辑动态的加到其他的 业务逻辑代码中,例如:事物管理,权限管理,日志管理等
2.如何实现aop
aop的实现基本上分为两种
- 基于Java回调函数技术的filter过滤器
- 基于Java反射机制的 代理模式,代理模式又分动态代理,静态代理 Java反射机制神秘链接
- 动态代理: 拦截器技术实现
- 静态代理
2.1 过滤器实现aop
- 过滤器是JavaEE标准,采用函数回调的方式进行。
- 过滤器通过请求的url进入容器后,还未进入Servlet之前进行预处理,并且在请求结束返回给前端之间进行后期处理。
- 以下贴出了实际项目代码中使用过滤器实现子系统根据当前用户设置权限功能,本着代码复用的目的,过滤器只写过滤逻辑,赋予权限的逻辑每个子系统都不一样,所以另写了 servlert来控制权限赋值
/**
* @category 过滤器 在主函数进入servlert容器后,未进入servlert前,对当前用户权限检查
*/
@WebFilter(urlPatterns = { "/*"})
public class LoginFilter implements Filter{
@Override
public void destroy() {
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest)request;
HttpServletResponse resp = (HttpServletResponse) response;
//初始化子应用session
HttpSession session = req.getSession();
session.setMaxInactiveInterval(36000);
//防盗链
//获取平台跳转传递的账号,放到session
String uid = req.getParameter(ResponseCode.session.uid);
if(uid!=null) {
session.setAttribute(ResponseCode.session.uid, uid);
}
//session 控制: 加载页面 or session 赋权限
String permission = (String)session.getAttribute(ResponseCode.session.permission.permission);
if(permission!=null) {
chain.doFilter(req,resp); //执行下个过滤器,没有就加载页面
}else {
resp.sendRedirect(ResponseCode.urlCode.LoginControllerUrl); //获取管理员权限
return;
}
}
}
通过session判断没有权限,跳转权限控制 servlert 进行权限赋值
/**
* @category 用户权限控制器
* @author wWX598039
*
*/
@Controller
public class PermissionController extends AbstractController{
@Autowired
private PermissionService permissionService;
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//防止乱码 返回格式设置
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
//全局变量
HttpServletRequest req = (HttpServletRequest)request;
HttpServletResponse resp = (HttpServletResponse) response;
//获取session参数
HttpSession session = req.getSession();
String uid = (String)session.getAttribute(ResponseCode.session.uid);
if(uid != null) {
//删除服务器与账号关联的session信息
session.removeAttribute(ResponseCode.session.uid);
session.removeAttribute(ResponseCode.session.permission.permission);
//获取账号权限
String permission = permissionService.getPermissionControllerByUser(uid);
//权限赋值
if(permission == null) {
resp.sendRedirect(ResponseCode.urlCode.errorUrl); //没权限不给访问
return;
}else { //赋予权限 重定向首页
session.setAttribute(ResponseCode.session.uid, uid);
if("2".equals(permission)){
session.setAttribute(ResponseCode.session.permission.permission, ResponseCode.session.permission.user);
resp.sendRedirect(ResponseCode.urlCode.HaUploadUrl);
return;
}
if("1".equals(permission)){
session.setAttribute(ResponseCode.session.permission.permission, ResponseCode.session.permission.admin);
resp.sendRedirect(ResponseCode.urlCode.HaUploadUrl);
return;
}
}
}else {
resp.sendRedirect(ResponseCode.urlCode.ErrorUrl);
return;
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException{
}
}
2.2 动态代理实现aop (目前只懂原理,缺少实际项目运用)
- 改别人的代码,不改变类的基础上去扩展新功能,需要用到
Application.xml
<?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: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-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
<context:annotation-config/>
<context:component-scan base-package="spring"></context:component-scan> <!-- 扫描初始化 -->
<aop:aspectj-autoproxy/> <!-- Spring实现aop -->
</beans>
业务逻辑A类的a()方法 要加到业务逻辑b,c,d中
具体实现为A类实现InvocationHandler接口,里面有一个object类对象target(被代理对象(b,c,d))
public class LogInterceptor implements InvocationHandler {
private Object target; //被代理对象
public Object getTarget() {
return target;
}
public void setTarget(Object target) {
this.target = target;
}
public void beforeMethod() {
System.out.println("start"); //a方法
}
public Object invoke(Object proxy, Method m, Object[] args)
throws Throwable {
beforeMethod(); //动态代理对象方法调用前加入a方法
m.invoke(target, args); //B,C,D类的方法里加入逻辑a方法
return null;
}
}
Example : 往B类的方法b里面添加逻辑A类的a方法:
public void testProxy() {
UserDAO userDAO = new UserDAOImpl(); //B类(被代理对象),需要交给A类LogInterceptor
LogInterceptor li = new LogInterceptor(); //A类
li.setTarget(userDAO); //A类设置被代理对象属性
UserDAO userDAOProxy = (UserDAO)Proxy.newProxyInstance(userDAO.getClass().getClassLoader(), userDAO.getClass().getInterfaces(), li); //获取被代理对象的代理对象
userDAOProxy.save(new User()); //执行b方法
}
Proxy.newProxyInstance()返回一个实现了A类的B类(组合起来),当我们调用B的业务逻辑b时,会将B类,b方法,b方法的参数传递给A类,并调用A类的invoke方法,先添加自己的业务逻辑a,再调用b方法,这样就在B不知情的情况下加入了扩展业务A的a方法
2.3 基于注解实现aop (目前只懂原理,缺少实际项目运用)
Spring框架_定时器(task)
- 适用于web应用 定时执行耗时比较长的有关数据方面的功能 例如: 解析整理大批量数据 生成报表查询用的中间表等等
1 xml配置
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation=
"http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-3.1.xsd">
<task:annotation-driven/>
</beans>
2.在代码中添加定时器注解
@Scheduled(cron="0 15 10 * * ? ") //每天23点执行解析代码
public void parserProduct() {
}