<prop key="current_session_context_class">thread</prop>作用

本文介绍了如何使用sessionFactory.getCurrentSession()方法来管理Hibernate会话。该方法能够将session与当前线程绑定,在事务结束后释放并关闭session。通过示例代码展示了如何开始一个事务、保存数据并提交事务。
sessionFactory.getCurrentSession()可以完成一系列的工作,当调用时,
hibernate将session绑定到当前线程,事务结束后,hibernate
将session从当前线程中释放,并且关闭session。当再次调用getCurrentSession
()时,将得到一个新的session,并重新开始这一系列工作。
这样调用方法如下:

Session session = HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();
Event theEvent = new Event();
theEvent.setTitle(title);
theEvent.setDate(theDate);
session.save(theEvent);
session.getTransaction().commit();

不需要close session了。.
from flask import Flask, render_template, redirect, url_for, request, flash import paho.mqtt.client as mqtt import json from threading import Thread from flask_sqlalchemy import SQLAlchemy from flask_login import LoginManager, UserMixin, login_user, login_required, logout_user, current_user from werkzeug.security import generate_password_hash, check_password_hash from flask_socketio import SocketIO from datetime import datetime from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes from cryptography.hazmat.primitives import padding from cryptography.hazmat.backends import default_backend import base64 from flask import request, jsonify from vosk import Model, KaldiRecognizer import wave import os from paddleocr import PaddleOCR from paddlehub.module.module import Module import cv2 # 初始化 Flask 和扩展 app = Flask(__name__) socketio = SocketIO(app) # 初始化 Flask-SocketIO app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///iot_130.db' app.config['SECRET_KEY'] = 'your_secret_key' app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False db = SQLAlchemy(app) login_manager = LoginManager(app) login_manager.login_view = 'login' # AES 配置 SECRET_KEY = b"your_secret_key".ljust(32, b'\0') # AES-256密钥(32字节) IV = b"16_byte_iv_12345" # 16字节的初始化向量 # AES解密函数 def decrypt_data(encrypted_data, key): backend = default_backend() cipher = Cipher(algorithms.AES(key), modes.CBC(IV), backend=backend) decryptor = cipher.decryptor() unpadder = padding.PKCS7(128).unpadder() decrypted = decryptor.update(base64.b64decode(encrypted_data)) + decryptor.finalize() unpadded_data = unpadder.update(decrypted) + unpadder.finalize() return unpadded_data.decode() # AES加密函数 def encrypt_data(data, key): backend = default_backend() cipher = Cipher(algorithms.AES(key), modes.CBC(IV), backend=backend) encryptor = cipher.encryptor() padder = padding.PKCS7(128).padder() padded_data = padder.update(data) + padder.finalize() encrypted = encryptor.update(padded_data) + encryptor.finalize() return base64.b64encode(encrypted).decode() # User 表 class User(UserMixin, db.Model): __tablename__ = 'User' id = db.Column(db.Integer, primary_key=True, autoincrement=True) username = db.Column(db.String(150), unique=True, nullable=False) password = db.Column(db.String(150), nullable=False) role = db.Column(db.String(50), default='user') # Device 表 class Device(db.Model): __tablename__ = 'Device' id = db.Column(db.Integer, primary_key=True, autoincrement=True) name = db.Column(db.String(150), nullable=False) type = db.Column(db.String(150), nullable=False) status = db.Column(db.String(50), default='offline') last_seen = db.Column(db.DateTime, default=None) # SensorData 表 class SensorData(db.Model): __tablename__ = 'SensorData' id = db.Column(db.Integer, primary_key=True, autoincrement=True) device_id = db.Column(db.Integer, db.ForeignKey('Device.id'), nullable=False) value = db.Column(db.Float, nullable=False) timestamp = db.Column(db.DateTime, default=datetime.utcnow) # Command 表 class Command(db.Model): __tablename__ = 'Command' id = db.Column(db.Integer, primary_key=True, autoincrement=True) device_id = db.Column(db.Integer, db.ForeignKey('Device.id'), nullable=False) command = db.Column(db.String(150), nullable=False) status = db.Column(db.String(50), default='pending') timestamp = db.Column(db.DateTime, default=datetime.utcnow) # 初始化数据库 with app.app_context(): db.create_all() @login_manager.user_loader def load_user(user_id): return User.query.get(int(user_id)) @app.route('/register', methods=['GET', 'POST']) def register(): if request.method == 'POST': username = request.form['username'] password = request.form['password'] hashed_password = generate_password_hash(password) # 检查用户名是否已存在 if User.query.filter_by(username=username).first(): flash('用户名已存在!') return redirect(url_for('register')) # 创建新用户 new_user = User(username=username, password=hashed_password) db.session.add(new_user) db.session.commit() flash('注册成功!请登录。') return redirect(url_for('login')) return render_template('register.html') @app.route('/login', methods=['GET', 'POST']) def login(): if request.method == 'POST': username = request.form['username'] password = request.form['password'] user = User.query.filter_by(username=username).first() if user and check_password_hash(user.password, password): login_user(user) return redirect(url_for('index')) flash('用户名或密码错误!') return render_template('login.html') @app.route('/logout') @login_required def logout(): logout_user() return redirect(url_for('login')) # 上传页面 @app.route('/upload', methods=['GET', 'POST']) @login_required def upload(): if request.method == 'POST': # 检查是否有文件上传 if 'file' not in request.files: flash('没有选择文件!') return redirect(request.url) file = request.files['file'] if file.filename == '': flash('没有选择文件!') return redirect(request.url) # 保存文件到 wav 目录 if file and file.filename.endswith('.wav'): filepath = os.path.join('wav', file.filename) file.save(filepath) # 使用 Vosk 模型进行语音识别 text = transcribe_audio(filepath) # 返回识别结果 return render_template('upload.html', text=text) return render_template('upload.html', text=None) @app.route('/image_upload', methods=['GET', 'POST']) @login_required def image_upload(): if request.method == 'POST': if 'image' not in request.files: flash('没有选择图像文件!') return redirect(request.url) image_file = request.files['image'] if image_file.filename == '': flash('没有选择图像文件!') return redirect(request.url) if image_file and image_file.filename.lower().endswith(('.png', '.jpg', '.jpeg')): image_path = os.path.join('static/uploads/images', image_file.filename) image_file.save(image_path) # 使用 PP-OCRv5 模型进行文字识别和图像检测 recognized_text = recognize_text(image_path) return render_template('image_upload.html', text=recognized_text) return render_template('image_upload.html', text=None) @app.route('/video_upload', methods=['GET', 'POST']) @login_required def video_upload(): if request.method == 'POST': if 'video' not in request.files: flash('没有选择视频文件!') return redirect(request.url) video_file = request.files['video'] if video_file.filename == '': flash('没有选择视频文件!') return redirect(request.url) if video_file and video_file.filename.lower().endswith(('.mp4', '.avi', '.mov')): video_path = os.path.join('static/uploads/videos', video_file.filename) video_file.save(video_path) # 使用 PaddleHub 模型进行宠物分类 classification_result = classify_pets_in_video(video_path) return render_template('video_upload.html', result=classification_result) return render_template('video_upload.html', result=None) def classify_pets_in_video(video_path): """使用 PaddleHub 模型对视频中的宠物进行分类""" try: # 加载 PaddleHub 的宠物分类模型 module = Module(name="resnet50_vd_animals") except Exception as e: print(f"模型加载失败: {e}") return # 打开视频文件 cap = cv2.VideoCapture(video_path) if not cap.isOpened(): print(f"无法打开视频文件: {video_path}") return frame_count = 0 results = [] while cap.isOpened(): ret, frame = cap.read() if not ret: break # 每隔一定帧数进行分类 if frame_count % 30 == 0: # 每30帧处理一次 print(f"正在处理第 {frame_count} 帧...") try: # 转换帧为 RGB 格式(PaddleHub 模型需要 RGB 格式) frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) # 使用 PaddleHub 模型进行分类 result = module.classification(images=[frame_rgb]) results.append(result) except Exception as e: print(f"处理第 {frame_count} 帧时出错: {e}") frame_count += 1 cap.release() print("视频处理完成!") return results def recognize_text(image_path): """使用 PP-OCRv5 模型识别图像中的文字并检测图像""" ocr = PaddleOCR( text_detection_model_name="PP-OCRv5_mobile_det", text_recognition_model_name="PP-OCRv5_mobile_rec", use_doc_orientation_classify=False, use_doc_unwarping=False, use_textline_orientation=False, ) result = ocr.predict(image_path) print("result:", result) # 打印结果以调试 return result[0]['rec_texts'] def transcribe_audio(filepath): """使用 Vosk 模型将音频转换为文本""" model_path = "models/vosk-model-small-cn-0.22" if not os.path.exists(model_path): raise FileNotFoundError("Vosk 模型未找到,请检查路径!") model = Model(model_path) wf = wave.open(filepath, "rb") rec = KaldiRecognizer(model, wf.getframerate()) result_text = "" while True: data = wf.readframes(4000) if len(data) == 0: break if rec.AcceptWaveform(data): result = rec.Result() result_text += json.loads(result).get("text", "") wf.close() return result_text # MQTT配置 MQTT_BROKER = "localhost" # 或EMQX服务器地址 MQTT_PORT = 1883 # 存储最新温度和风扇状态 mytemp = None myfan = "off" def init_device(device_name, device_type): """初始化设备到数据库""" with app.app_context(): device = Device.query.filter_by(name=device_name).first() if not device: device = Device(name=device_name, type=device_type, status="offline") db.session.add(device) db.session.commit() def save_sensor_data(device_name, value): """保存传感器数据到 SensorData 表""" with app.app_context(): device = Device.query.filter_by(name=device_name).first() if device: sensor_data = SensorData(device_id=device.id, value=value) db.session.add(sensor_data) db.session.commit() def save_command(device_name, command): """保存控制指令到 Command 表""" with app.app_context(): device = Device.query.filter_by(name=device_name).first() if device: cmd = Command(device_id=device.id, command=command) db.session.add(cmd) db.session.commit() def on_connect(client, userdata, flags, rc): print(f"MQTT连接结果: {rc}") client.subscribe("topic/temp") # 订阅温度主题 def on_message(client, userdata, msg): global mytemp, myfan try: if msg.topic == "topic/temp": encrypted_payload = msg.payload.decode() decrypted_payload = decrypt_data(encrypted_payload, SECRET_KEY) payload = json.loads(decrypted_payload) mytemp = payload["temp"] print(f"解密温度数据: {mytemp}°C") # 保存传感器数据到数据库 save_sensor_data("temp", mytemp) # 根据温度控制风扇 if mytemp >= 30: control_fan("on") myfan = "on" else: control_fan("off") myfan = "off" # 实时推送温度数据到前端 socketio.emit('sensor_data', {'temp': mytemp, 'fan': myfan}) except Exception as e: print(f"解密失败或处理异常: {e}") def control_fan(command): """发送加密控制指令给风扇并保存到数据库""" payload = json.dumps({"fan": command}) encrypted_payload = encrypt_data(payload.encode(), SECRET_KEY) mqtt_client.publish("topic/fan", encrypted_payload) print(f"发送加密控制指令: {encrypted_payload}") # 保存控制指令到数据库 save_command("fan", command) def run_mqtt_client(): global mqtt_client mqtt_client = mqtt.Client() mqtt_client.on_connect = on_connect mqtt_client.on_message = on_message mqtt_client.username_pw_set("admin", "admin") # 账号密码验证 mqtt_client.connect(MQTT_BROKER, MQTT_PORT, 60) mqtt_client.loop_forever() @app.route('/') @login_required # 保护 chart.html def index(): return render_template('chart.html') # 渲染前端页面 if __name__ == "__main__": # 初始化设备 with app.app_context(): init_device("temp", "sensor") init_device("fan", "actuator") # 启动MQTT客户端线程 mqtt_thread = Thread(target=run_mqtt_client) mqtt_thread.daemon = True mqtt_thread.start() # 启动Flask-SocketIO应用,启用TLS socketio.run(app, host="0.0.0.0", port=9000, debug=False, ssl_context=("ca/server.crt", "ca/server.key"))怎么改使用一个页面上传按钮,可同时上传图像、音频、视频,并将识别结果显示在该页面。
06-12
请分析下面代码:<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans> <bean id="sessionFactory" class="com.smics.apps.core.persistence.impl.DefaultSessionFactoryBean"> <property name="dataSource"><ref bean="dataSource"/></property> <property name="mappingResources"> <list> <value>com/smics/apps/erc/domain/Erc.hbm.xml</value> <value>com/smics/apps/erc/domain/admin/Admin.hbm.xml</value> <value>com/smics/apps/erc/domain/mfgAssigner/MfgAssigner.hbm.xml</value> <value>com/smics/apps/erc/domain/specialDuty/specialDutyInfo.hbm.xml</value> <value>com/smics/apps/erc/domain/QEMaintain/QEMaintain.hbm.xml</value> <value>com/smics/apps/erc/domain/Workflow.hbm.xml</value> <value>com/smics/apps/erc/domain/MailNotification.hbm.xml</value> </list> </property> <property name="hibernateProperties"><ref bean="hibernateProperties"/></property> <property name="entityInterceptor"><bean class="com.smics.apps.sso.util.AuditInterceptor"/></property> </bean> <!-- Transaction manager for a single Hibernate SessionFactory (alternative to JTA) --> <bean id="transactionManager" class="org.springframework.orm.hibernate.HibernateTransactionManager"> <property name="sessionFactory"><ref local="sessionFactory"/></property> </bean> <!-- SimpleSecurityService, you may implement the SecurityService interface for your application --> <bean id="securityService" class="com.smics.apps.security.service.impl.SimpleSecurityService"> <property name="permissionGroup"> <map> <entry key="SUPERADMIN"> <list> <value>E001751</value> <value>E015876</value> </list> </entry> <entry key="DEVELOPER"> <list> <value>E015876</value> <value>E019558</value> <value>E001751</value> </list> </entry> <entry key="WEBTOOLS"> <list> <value>E015876</value> <value>E019558</value> <value>E001751</value> </list> </entry> </map> </property> </bean> <bean id="workflowStore" class="com.opensymphony.workflow.spi.hibernate.SpringHibernateWorkflowStore"> <property name="sessionFactory"><ref local="sessionFactory"/></property> </bean> <bean id="workflowFactory" class="com.smics.apps.workflow.WorkflowFactory"> <property name="workflows"> <map> <entry key="ercFlow"><value>com/smics/apps/erc/workflow/ErcWorkflow.xml</value></entry> </map> </property> </bean> <bean id="osworkflowConfiguration" class="com.opensymphony.workflow.config.SpringConfiguration"> <property name="store"><ref local="workflowStore"/></property> <property name="factory"><ref local="workflowFactory"/></property> </bean> <bean id="workflowServiceTarget" class="com.smics.apps.workflow.service.impl.WorkflowServiceImpl" autowire="byName"/> <bean id="workflowService" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> <property name="transactionManager"><ref local="transactionManager"/></property> <property name="target"><ref local="workflowServiceTarget"/></property> <property name="transactionAttributes"> <props> <prop key="*">PROPAGATION_REQUIRED</prop> </props> </property> </bean> <!-- Transactional proxy for the services --> <bean id="baseTxProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" lazy-init="true"> <property name="transactionManager"><ref bean="transactionManager"/></property> <property name="transactionAttributes"> <props> <prop key="*">PROPAGATION_REQUIRED,readOnly</prop> <prop key="create*">PROPAGATION_REQUIRED</prop> <prop key="delete*">PROPAGATION_REQUIRED</prop> <prop key="start*">PROPAGATION_REQUIRED</prop> <prop key="complete*">PROPAGATION_REQUIRED</prop> <prop key="update*">PROPAGATION_REQUIRED</prop> <prop key="generate*">PROPAGATION_REQUIRED</prop> <prop key="send*">PROPAGATION_REQUIRED</prop> <prop key="forward*">PROPAGATION_REQUIRED</prop> <prop key="add*">PROPAGATION_REQUIRED</prop> <prop key="withdraw*">PROPAGATION_REQUIRED</prop> <prop key="change*">PROPAGATION_REQUIRED</prop> <prop key="copy*">PROPAGATION_REQUIRED</prop> <prop key="autoJob*">PROPAGATION_REQUIRED</prop> <prop key="lock*">PROPAGATION_REQUIRED</prop> </props> </property> <property name="preInterceptors"> <list> <ref bean="serviceExceptionInterceptor"/> </list> </property> </bean> <bean id ="serviceExceptionInterceptor" class="com.smics.apps.erc.Interceptor.ServiceExceptionInterceptor"> <property name="systemOwner"><value>E001751</value></property> <property name="employeeService"><ref bean="employeeService" /></property> <property name="sessionFactory"><ref bean="sessionFactory" /></property> </bean> <bean id="Alert" parent="mailMessage"> <property name="subject"><value>e-SplitRuncard: System Alert</value></property> <property name="templateName"><value>erc/workflow/mail/alert.ftl</value></property> </bean> <bean id="ercService" parent="baseTxProxy"> <property name="target"> <bean class="com.smics.apps.erc.service.impl.ErcServiceImpl" autowire="byName"/> </property> </bean> <bean id="hrService" class="com.smics.apps.erc.service.impl.HrServiceImpl"> <property name="sessionFactory"><ref bean="exporthrSessionFactory"/></property> </bean> <bean id="adminService" parent="baseTxProxy"> <property name="target"> <bean class="com.smics.apps.erc.service.impl.AdminServiceImpl" autowire="byName"/> </property> </bean> <bean id="mfgAssignerService" parent="baseTxProxy"> <property name="target"> <bean class="com.smics.apps.erc.service.impl.MfgAssignerServiceImpl" autowire="byName"/> </property> </bean> <bean id="specialDutyService" parent="baseTxProxy"> <property name="target"> <bean class="com.smics.apps.erc.service.impl.SpecialDutyServiceImpl" autowire="byName"/> </property> </bean> <bean id="maintainService" parent="baseTxProxy"> <property name="target"> <bean class="com.smics.apps.erc.service.impl.QEMaintainServiceImpl" autowire="byName"/> </property> </bean> <bean id="mailNotificationService" parent="baseTxProxy"> <property name="target"> <bean class="com.smics.apps.mail.service.impl.MailNotificationServiceImpl" autowire="byName"/> </property> </bean> <bean id="Approval" parent="mailMessage"> <property name="subject"><value>e-SplitRuncard system needs your approval</value></property> <property name="templateName"><value>erc/workflow/mail/Approval.ftl</value></property> </bean> <bean id="Reject" parent="mailMessage"> <property name="subject"><value>Your e-SplitRuncard system case be rejected</value></property> <property name="templateName"><value>erc/workflow/mail/Reject.ftl</value></property> </bean> <bean id="Complete" parent="mailMessage"> <property name="subject"><value>Your e-SplitRuncard system case be completed</value></property> <property name="templateName"><value>erc/workflow/mail/Complete.ftl</value></property> </bean> <bean id="Withdraw" parent="mailMessage"> <property name="subject"><value>Your e-SplitRuncard system case be withdrew</value></property> <property name="templateName"><value>erc/workflow/mail/WithDraw.ftl</value></property> </bean> <bean id="unlockMail" parent="mailMessage"> <property name="subject"><value>Product version changed! Please check the e-SplitRunCrd Before unlock it!</value></property> <property name="templateName"><value>erc/workflow/mail/unlockMail.ftl</value></property> </bean> <bean id="mailAdmin" parent="mailMessage"> <property name="subject"><value>Product version changed! Please check the e-SplitRunCrd Before unlock it!</value></property> <property name="templateName"><value>erc/workflow/mail/mailAdmin.ftl</value></property> </bean> <bean id="mailApplicant" parent="mailMessage"> <property name="subject"><value>e-SplitRuncard system change hold owner failure!</value></property> <property name="templateName"><value>erc/workflow/mail/mailApplicant.ftl</value></property> </bean> <bean id="mailAdminForHoldOwner" parent="mailMessage"> <property name="subject"><value>e-SplitRuncard system change hold owner failure!</value></property> <property name="templateName"><value>erc/workflow/mail/mailAdminForHoldOwner.ftl</value></property> </bean> <bean id="sendMailTimerTask" class="org.springframework.scheduling.timer.ScheduledTimerTask"> <property name="timerTask"> <bean class="com.smics.apps.mail.SendMailTimerTask" autowire="byName"/> </property> <property name="fixedRate"><value>true</value></property> <property name="delay"><value>5000</value></property> <property name="period"><value>120000</value></property> </bean> <bean id="timerFactory" class="org.springframework.scheduling.timer.TimerFactoryBean"> <property name="scheduledTimerTasks"> <list> <!--ref local="sendMailTimerTask"/--> </list> </property> </bean> <!-- Schedule--> <bean id="autoRunJob" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> <property name="targetObject"><ref bean="ercService"/></property> <property name="targetMethod"><value>autoJob</value></property> </bean> <bean id="autoRunJobTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean"> <property name="jobDetail"> <ref bean="autoRunJob"/> </property> <property name="cronExpression"> <value>0 0 * * * ?</value> </property> </bean> <bean id="deleteDraft" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> <property name="targetObject"><ref bean="ercService"/></property> <property name="targetMethod"><value>deleteDraft</value></property> </bean> <bean id="autoDeleteDraftTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean"> <property name="jobDetail"> <ref bean="deleteDraft"/> </property> <property name="cronExpression"> <value>0 42 14 * * ?</value> </property> </bean> <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <property name="triggers"> <list> <!--ref local="autoRunJobTrigger"/> <ref local="autoDeleteDraftTrigger"/--> </list> </property> </bean> </beans>
最新发布
10-10
这段 XML 配置文件是基于 **Spring 2.x** 的传统 Spring Bean 配置方式,用于定义 Spring 容器中的 Bean、事务管理、Hibernate 会话工厂、工作流配置、邮件服务、定时任务等。以下是对该配置文件的详细分析: --- ### 一、核心组件配置 #### 1. `sessionFactory`(Hibernate 会话工厂) ```xml <bean id="sessionFactory" class="com.smics.apps.core.persistence.impl.DefaultSessionFactoryBean"> <property name="dataSource"><ref bean="dataSource"/></property> <property name="mappingResources">...</property> <property name="hibernateProperties"><ref bean="hibernateProperties"/></property> <property name="entityInterceptor"><bean class="com.smics.apps.sso.util.AuditInterceptor"/></property> </bean> ``` - **作用**:创建 Hibernate 的 `SessionFactory`,用于管理数据库连接和实体映射。 - **关键配置**: - `dataSource`:引用数据库连接池。 - `mappingResources`:指定多个 `.hbm.xml` 映射文件,用于定义实体类与数据库表的映射关系。 - `hibernateProperties`:引用 Hibernate 的配置参数(如方言、SQL显示等)。 - `entityInterceptor`:设置审计拦截器,用于记录操作日志或权限控制。 #### 2. `transactionManager`(事务管理器) ```xml <bean id="transactionManager" class="org.springframework.orm.hibernate.HibernateTransactionManager"> <property name="sessionFactory"><ref local="sessionFactory"/></property> </bean> ``` - **作用**:管理 Hibernate 的事务。 - **说明**:使用 `HibernateTransactionManager` 实现事务控制,适合单数据源的场景。 --- ### 二、安全与权限配置 #### `securityService`(权限服务) ```xml <bean id="securityService" class="com.smics.apps.security.service.impl.SimpleSecurityService"> <property name="permissionGroup"> <map> <entry key="SUPERADMIN">...</entry> <entry key="DEVELOPER">...</entry> <entry key="WEBTOOLS">...</entry> </map> </property> </bean> ``` - **作用**:定义角色与权限的映射关系。 - **说明**:每个角色(如 `SUPERADMIN`)对应一个权限列表,权限以字符串形式标识(如 `E001751`)。 --- ### 三、工作流配置(OSWorkflow) #### 1. `workflowStore`(持久化存储) ```xml <bean id="workflowStore" class="com.opensymphony.workflow.spi.hibernate.SpringHibernateWorkflowStore"> <property name="sessionFactory"><ref local="sessionFactory"/></property> </bean> ``` - **作用**:将工作流状态保存到数据库中,使用 Hibernate 实现持久化。 #### 2. `workflowFactory`(流程定义) ```xml <bean id="workflowFactory" class="com.smics.apps.workflow.WorkflowFactory"> <property name="workflows"> <map> <entry key="ercFlow"><value>com/smics/apps/erc/workflow/ErcWorkflow.xml</value></entry> </map> </property> </bean> ``` - **作用**:加载流程定义文件(XML 格式)。 - **说明**:`ercFlow` 是流程名称,对应 `ErcWorkflow.xml` 文件。 #### 3. `osworkflowConfiguration`(工作流配置) ```xml <bean id="osworkflowConfiguration" class="com.opensymphony.workflow.config.SpringConfiguration"> <property name="store"><ref local="workflowStore"/></property> <property name="factory"><ref local="workflowFactory"/></property> </bean> ``` - **作用**:整合 `workflowStore` 和 `workflowFactory`,作为工作流的配置中心。 --- ### 四、服务代理与事务控制 #### `baseTxProxy`(事务代理模板) ```xml <bean id="baseTxProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" lazy-init="true"> <property name="transactionManager"><ref bean="transactionManager"/></property> <property name="transactionAttributes"> <props> <prop key="*">PROPAGATION_REQUIRED,readOnly</prop> <prop key="create*">PROPAGATION_REQUIRED</prop> ... </props> </property> </bean> ``` - **作用**:为业务服务提供事务管理的代理模板。 - **说明**: - 对所有方法设置默认事务传播行为为 `PROPAGATION_REQUIRED`,并设置为只读。 - 对特定方法名(如 `create*`、`delete*`)设置为可写事务。 #### 具体服务代理(如 `ercService`) ```xml <bean id="ercService" parent="baseTxProxy"> <property name="target"> <bean class="com.smics.apps.erc.service.impl.ErcServiceImpl" autowire="byName"/> </property> </bean> ``` - **作用**:基于 `baseTxProxy` 模板创建事务代理对象。 - **说明**:通过继承方式复用事务配置,提高配置复用性。 --- ### 五、邮件服务配置 #### 邮件模板(如 `Approval`、`Reject`) ```xml <bean id="Approval" parent="mailMessage"> <property name="subject"><value>e-SplitRuncard system needs your approval</value></property> <property name="templateName"><value>erc/workflow/mail/Approval.ftl</value></property> </bean> ``` - **作用**:定义邮件主题与模板路径。 - **说明**:使用 FreeMarker 模板(`.ftl`)生成邮件内容。 #### 邮件服务代理 ```xml <bean id="mailNotificationService" parent="baseTxProxy"> <property name="target"> <bean class="com.smics.apps.mail.service.impl.MailNotificationServiceImpl" autowire="byName"/> </property> </bean> ``` - **作用**:封装邮件发送逻辑,并提供事务支持。 --- ### 六、定时任务配置(Quartz) #### 1. `autoRunJob`(定时任务 Job) ```xml <bean id="autoRunJob" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> <property name="targetObject"><ref bean="ercService"/></property> <property name="targetMethod"><value>autoJob</value></property> </bean> ``` - **作用**:调用 `ercService.autoJob()` 方法作为定时任务执行体。 #### 2. `autoRunJobTrigger`(触发器) ```xml <bean id="autoRunJobTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean"> <property name="jobDetail"><ref bean="autoRunJob"/></property> <property name="cronExpression"><value>0 0 * * * ?</value></property> </bean> ``` - **作用**:按 Cron 表达式定时触发任务。 - **示例**:`0 0 * * * ?` 表示每小时执行一次。 #### 3. `SchedulerFactoryBean`(任务调度器) ```xml <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <property name="triggers"> <list> <!--ref local="autoRunJobTrigger"/--> <!--ref local="autoDeleteDraftTrigger"/--> </list> </property> </bean> ``` - **作用**:启动 Quartz 调度器,管理所有定时任务。 --- ### 七、拦截器与异常处理 #### `serviceExceptionInterceptor` ```xml <bean id="serviceExceptionInterceptor" class="com.smics.apps.erc.Interceptor.ServiceExceptionInterceptor"> <property name="systemOwner"><value>E001751</value></property> <property name="employeeService"><ref bean="employeeService" /></property> <property name="sessionFactory"><ref bean="sessionFactory" /></property> </bean> ``` - **作用**:自定义服务层拦截器,处理业务异常。 - **说明**:可用于记录日志、发送通知、权限校验等。 --- ### 八、总结 | 模块 | 功能 | |------|------| | `sessionFactory` | Hibernate 会话工厂,管理实体映射与数据库连接 | | `transactionManager` | 事务管理器,支持声明式事务 | | `securityService` | 角色与权限映射 | | `workflowStore`, `workflowFactory` | 工作流引擎配置 | | `baseTxProxy` | 服务代理模板,提供事务控制 | | `mailMessage` | 邮件模板定义 | | `Quartz` 定时任务 | 定时执行业务逻辑 | | `ServiceExceptionInterceptor` | 自定义异常拦截器 | --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值