重慶分公司,新征程啟航
為企業提供網站建設、域名注冊、服務器等服務
為企業提供網站建設、域名注冊、服務器等服務
在配置文件里配置 Bean 時, 有時需要在 Bean 的配置里混入系統部署的細節信息(例如: 文件路徑, 數據源配置信息等). 而這些部署細節實際上需要和 Bean 配置相分離
網站制作、網站設計的關注點不是能為您做些什么網站,而是怎么做網站,有沒有做好網站,給成都創新互聯一個展示的機會來證明自己,這并不會花費您太多時間,或許會給您帶來新的靈感和驚喜。面向用戶友好,注重用戶體驗,一切以用戶為中心。
Spring 提供了一個 PropertyPlaceholderConfigurer 的 BeanFactory 后置處理器, 這個處理器允許用戶將 Bean 配置的部分內容外移到屬性文件中. 可以在 Bean 配置文件里使用形式為 ${var} 的變量, PropertyPlaceholderConfigurer 從屬性文件里加載屬性, 并使用這些屬性來替換變量.
是一個支持運行時查詢和操作對象圖的強大的表達式語言
通過 SpEL 可以實現:
驗證郵箱
^[_A-Za-z0-9-]+(\.[_A-Za-z0-9-]+)"+"*@[A-Za-z0-9]+(\.[A-Za-z0-9]+)*(\.[A-Za-z]{2,})$
在初始化方法被調用前后, Spring 將把每個 Bean 實例分別傳遞給上述接口的以下兩個方法:
public class MyBeanPostProcesser implements BeanPostProcessor {
// 在init-method之前調用
@Override
public Object postProcessBeforeInitialization(Object o, String s) throws BeansException {
System.out.println("postProcessBeforeInitialization: " + s);
return o;
}
// 在init-method之后調用
@Override
public Object postProcessAfterInitialization(Object o, String s) throws BeansException {
System.out.println("postProcessAfterInitialization: " + s);
return o;
}
}
//Bean 后置處理器允許在調用初始化方法前后對 Bean 進行額外的處理.
//Bean 后置處理器對 IOC 容器里的所有 Bean 實例逐一處理, 而非單一實例.
// 其典型應用是: 檢查 Bean 屬性的正確性或根據特定的標準更改 Bean 的屬性.
//采用前置和后置處理之后
//首先運行構造函數
//然后給屬性賦值
//然后訪問前置處理函數
//然后訪問init函數
//然后訪問后置處理函數
//然后輸出結果
//最后訪問destroy函數
構造器, 普通字段(即使是非 public), 一切具有參數的方法都可以應用@Authwired 注解
默認情況下, 所有使用 @Authwired 注解的屬性都需要被設置. 當 Spring 找不到匹配的 Bean 裝配屬性時, 會拋出異常, 若某一屬性允許不被設置, 可以設置 @Authwired 注解的 required 屬性為 false
默認情況下, 當 IOC 容器里存在多個類型兼容的 Bean 時, 通過類型的自動裝配將無法工作. 此時可以在 @Qualifier 注解里提供 Bean 的名稱. Spring 允許對方法的入參標注 @Qualifiter 已指定注入 Bean 的名稱
@Authwired 注解也可以應用在數組類型的屬性上, 此時 Spring 將會把所有匹配的 Bean 進行自動裝配.
@Authwired 注解也可以應用在集合屬性上, 此時 Spring 讀取該集合的類型信息, 然后自動裝配所有與之兼容的 Bean.
是一種新的方法論, 是對傳統 OOP(Object-Oriented Programming, 面向對象編程) 的補充.
AOP 的主要編程對象是切面(aspect), 而切面模塊化橫切關注點.
在應用 AOP 編程時, 仍然需要定義公共功能, 但可以明確的定義這個功能在哪里, 以什么方式應用, 并且不必修改受影響的類. 這樣一來橫切關注點就被模塊化到特殊的對象(切面)里.
AOP 的好處:
AspectJ:Java 社區里最完整最流行的 AOP 框架.在 Spring2.0 以上版本中, 可以使用基于 AspectJ 注解或基于 XML 配置的 AOP
依賴包:
- aopalliance-1.0.jar
- aspectjrt.jar
- aspectjtools.jar
- aspectjweaver.jar
- org.aspectj.matcher.jar
@Around: 環繞通知, 圍繞著方法執行
@Pointcut 將多個被限制的bean或者bean方法合并為一個集合,AspectJ通知注解可以直接調用合并切入點的方法,
如: combinePointCut
@Aspect
@Order(0)
public class AspectProcessor {
// 合并切入點
@Pointcut("execution(* com.demo.aop.aspect.CalculatorImpl.*(..)))")
public void combinePointCut(){}
// 此函數在指定的bean方法執行前響應
// @Before("execution (* com.demo.aop.aspect.CalculatorImpl.*(..))")
@Before("combinePointCut()")
public void beforeAspectProcessor(JoinPoint joinPoint){
System.out.println("beforeAspectProcessor method name: " + joinPoint.getSignature().getName());
System.out.println("beforeAspectProcessor method args: " + Arrays.asList(joinPoint.getArgs()));
}
// 此函數在指定的bean方法執行后響應
// @After("execution (* com.demo.aop.aspect.CalculatorImpl.*(..))")
@After("combinePointCut()")
public void afterAspectProcessor(JoinPoint joinPoint){
System.out.println("afterAspectProcessor method name: " + joinPoint.getSignature().getName());
System.out.println("afterAspectProcessor method args: " + Arrays.asList(joinPoint.getArgs()));
}
// 此函數在指定的bean方法執行前、后響應
// @Around("combinePointCut()")
// public void around(ProceedingJoinPoint pjp) throws Throwable{
// System.out.println("已經記錄下操作日志@Around 方法執行前");
// pjp.proceed();
// System.out.println("已經記錄下操作日志@Around 方法執行后");
// }
// 如果只想在連接點返回的時候記錄, 應使用返回通知代替后置通知
@AfterReturning(value = "combinePointCut()", returning = "result")
public void afterReturningAspectProcessor(JoinPoint joinPoint, Object result){
System.out.println("afterReturningAspectProcessor method name: " + joinPoint.getSignature().getName());
System.out.println("afterReturningAspectProcessor method args: " + Arrays.asList(joinPoint.getArgs()));
System.out.println("afterReturningAspectProcessor method result: " + result);
}
// 異常通知
@AfterThrowing(value = "combinePointCut()", throwing = "e")
public void afterThrowingAspectProcessor(JoinPoint joinPoint, Exception e){
System.out.println("afterThrowingAspectProcessor method name: " + joinPoint.getSignature().getName());
System.out.println("afterThrowingAspectProcessor method args: " + Arrays.asList(joinPoint.getArgs()));
System.out.println("afterThrowingAspectProcessor method throwing: " + e);
}
}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;
/**
* Created by plusplusxu on 2017/10/23.
*
* 動態代理模式主要用來做方法的增強,讓你可以在不修改源碼的情況下,增強一些方法,
* 在方法執行前后做任何你想做的事情(甚至根本不去執行這個方法),
* 因為在InvocationHandler的invoke方法中,你可以直接獲取正在調用方法對應的Method對象,
* 具體應用的話,比如可以添加調用日志,做事務控制等。
* 動態代理是設計模式當中代理模式的一種。
*/
@Repository
public class CalculatorImplProxy {
@Autowired
private Calculator target;
public Calculator getProxy(){
Calculator proxy = null;
// 代理對象由哪一個加載器加載
ClassLoader loader = target.getClass().getClassLoader();
// 代理對象的內容
Class[] interfaces = new Class[]{Calculator.class};
// 當調用代理對象的方法的時候,該方法被執行
InvocationHandler h = new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 代理對象方法執行前操作
System.out.println("method: " + method.getName() + " " + " args: " + Arrays.asList(args));
Object result = method.invoke(target, args);
// 代理對象方法執行后操作
System.out.println("method: " + method.getName() + " " + " args: " + Arrays.asList(args) + " result: " + result);
return result;
}
};
proxy = (Calculator)Proxy.newProxyInstance(loader, interfaces, h);
return proxy;
}
}
作為 Spring JDBC 框架的核心, JDBC 模板的設計目的是為不同類型的 JDBC 操作提供模板方法. 每個模板方法都能控制整個過程, 并允許覆蓋過程中的特定任務. 通過這種方式, 可以在盡可能保留靈活性的情況下, 將數據庫存取的工作量降到最低.
該類聲明了 jdbcTemplate 屬性, 它可以從 IOC 容器中注入, 或者自動從數據源中創建.
package com.MySQL;
import org.springframework.jdbc.core.BatchPreparedStatementSetter;
import org.springframework.jdbc.core.JdbcTemplate;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.List;
/**
* Created by plusplusxu on 2017/10/25.
*
* 操作mysql的數據類
*
* JdbcTemplate 類被設計成為線程安全的, 所以可以再 IOC 容器中聲明它的單個實例, 并將這個實例注入到所有的 DAO 實例中.
*/
public class ProjectDao {
public ProjectDao(JdbcTemplate jdbcTemplateObject) {
this.jdbcTemplateObject = jdbcTemplateObject;
}
public ProjectDao() {
}
public JdbcTemplate getJdbcTemplateObject() {
return jdbcTemplateObject;
}
public void setJdbcTemplateObject(JdbcTemplate jdbcTemplateObject) {
this.jdbcTemplateObject = jdbcTemplateObject;
}
// spring 提供的訪問數據庫的工具類,需要配置javax.sql.DataSource
// 本例中在applicationContext中配置的mysql數據源
private JdbcTemplate jdbcTemplateObject;
// 添加一條項目記錄
// tbl_devops_project為vsdo數據庫的項目表(Project)
public void addproject(Project project) {
String sql = "INSERT INTO tbl_devops_project(name,public,language,description," +
"admin, members, gitlab_id,gitlab_url,code_styles,sonar_lint_server_url) " +
"VALUES(?,?,?,?,?,?,?,?,?,?)";
try {
jdbcTemplateObject.update(sql, project.getName(),project.getPub(),project.getLanguage(),project.getDescription(),
project.getAdmin(),project.getMembers(),project.getGitlab_id(),
project.getGitlab_url(),project.getCode_styles(),project.getSonar_lint_server_url());
}
catch (Exception e){
System.out.println(e);
}
return ;
}
// 根據項目名刪除記錄
public void delprojectbyname(String name) {
String sql = "DELETE FROM tbl_devops_project WHERE name=?";
try {
jdbcTemplateObject.update(sql,name);
}
catch (Exception e){
System.out.println(e);
}
return ;
}
// 刪除所有項目
public void delallproject() {
String sql = "DELETE FROM tbl_devops_project";
try {
jdbcTemplateObject.update(sql);
}
catch (Exception e){
System.out.println(e);
}
return ;
}
// 更新某個項目
public void updproject(Project project) {
String sql = "UPDATE tbl_devops_project set description=? WHERE name=?";
try {
jdbcTemplateObject.update(sql,project.getDescription(), project.getName());
}
catch (Exception e){
System.out.println(e);
}
return ;
}
// 獲取所有項目
public List allproject() {
List projects = null;
String sql = "SELECT * FROM tbl_devops_project";
try {
// ProjectMapper 項目表的映射類
projects = jdbcTemplateObject.query(sql, new ProjectMapper());
}
catch (Exception e){
System.out.println(e);
}
return projects;
}
// 查詢項目名對應的記錄
public List queryprojectbyname(String name) {
List projects = null;
String sql = "SELECT * FROM tbl_devops_project WHERE name=?";
try {
projects = jdbcTemplateObject.query(sql, new Object[]{name}, new ProjectMapper());
}
catch (Exception e){
System.out.println(e);
}
return projects;
}
// 打印所有項目
public void displayall(){
List projects = allproject();
for(Project s : projects){
System.out.println(s);
}
}
// 批量插入
public void insertBatch(final List projects){
String sql = "INSERT INTO tbl_devops_project(name,public,language,description," +
"admin, members, gitlab_id,gitlab_url,code_styles,sonar_lint_server_url) " +
"VALUES(?,?,?,?,?,?,?,?,?,?)";
jdbcTemplateObject.batchUpdate(sql, new BatchPreparedStatementSetter() {
@Override
public void setValues(PreparedStatement ps, int i) throws SQLException {
Project project = projects.get(i);
ps.setString(1, project.getName());
ps.setBoolean(2, project.getPub());
ps.setString(3, project.getLanguage());
ps.setString(4, project.getDescription());
ps.setString(5, project.getAdmin());
ps.setString(6, project.getMembers());
ps.setInt(7, project.getGitlab_id());
ps.setString(8, project.getGitlab_url());
ps.setString(9, project.getCode_styles());
ps.setString(10, project.getSonar_lint_server_url());
}
@Override
public int getBatchSize() {
return projects.size();
}
});
}
}
package com.mysql;
import org.springframework.jdbc.core.BatchPreparedStatementSetter;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.List;
/**
* Created by plusplusxu on 2017/10/26.
*
* 繼承于JdbcDaoSupport,直接封裝了JdbcTemplate,寫起來更方便
*
* 該類聲明了 jdbcTemplate 屬性, 它可以從 IOC 容器中注入, 或者自動從數據源中創建.
*
*/
public class JdbcDaoSupportImpl extends JdbcDaoSupport {
// 添加一條項目記錄
// tbl_devops_project為vsdo數據庫的項目表(Project)
public void addproject(Project project) {
String sql = "INSERT INTO tbl_devops_project(name,public,language,description," +
"admin, members, gitlab_id,gitlab_url,code_styles,sonar_lint_server_url) " +
"VALUES(?,?,?,?,?,?,?,?,?,?)";
try {
this.getJdbcTemplate().update(sql, project.getName(),project.getPub(),project.getLanguage(),project.getDescription(),
project.getAdmin(),project.getMembers(),project.getGitlab_id(),
project.getGitlab_url(),project.getCode_styles(),project.getSonar_lint_server_url());
}
catch (Exception e){
System.out.println(e);
}
return ;
}
// 根據項目名刪除記錄
public void delprojectbyname(String name) {
String sql = "DELETE FROM tbl_devops_project WHERE name=?";
try {
this.getJdbcTemplate().update(sql,name);
}
catch (Exception e){
System.out.println(e);
}
return ;
}
// 刪除所有項目
public void delallproject() {
String sql = "DELETE FROM tbl_devops_project";
try {
this.getJdbcTemplate().update(sql);
}
catch (Exception e){
System.out.println(e);
}
return ;
}
// 更新某個項目
public void updproject(Project project) {
String sql = "UPDATE tbl_devops_project set description=? WHERE name=?";
try {
this.getJdbcTemplate().update(sql,project.getDescription(), project.getName());
}
catch (Exception e){
System.out.println(e);
}
return ;
}
// 獲取所有項目
public List allproject() {
List projects = null;
String sql = "SELECT * FROM tbl_devops_project";
try {
// ProjectMapper 項目表的映射類
projects = this.getJdbcTemplate().query(sql, new ProjectMapper());
}
catch (Exception e){
System.out.println(e);
}
return projects;
}
// 查詢項目名對應的記錄
public List queryprojectbyname(String name) {
List projects = null;
String sql = "SELECT * FROM tbl_devops_project WHERE name=?";
try {
projects = this.getJdbcTemplate().query(sql, new Object[]{name}, new ProjectMapper());
}
catch (Exception e){
System.out.println(e);
}
return projects;
}
// 打印所有項目
public void displayall(){
List projects = allproject();
for(Project s : projects){
System.out.println(s);
}
}
// 批量插入
public void insertBatch(final List projects){
String sql = "INSERT INTO tbl_devops_project(name,public,language,description," +
"admin, members, gitlab_id,gitlab_url,code_styles,sonar_lint_server_url) " +
"VALUES(?,?,?,?,?,?,?,?,?,?)";
this.getJdbcTemplate().batchUpdate(sql, new BatchPreparedStatementSetter() {
@Override
public void setValues(PreparedStatement ps, int i) throws SQLException {
Project project = projects.get(i);
ps.setString(1, project.getName());
ps.setBoolean(2, project.getPub());
ps.setString(3, project.getLanguage());
ps.setString(4, project.getDescription());
ps.setString(5, project.getAdmin());
ps.setString(6, project.getMembers());
ps.setInt(7, project.getGitlab_id());
ps.setString(8, project.getGitlab_url());
ps.setString(9, project.getCode_styles());
ps.setString(10, project.getSonar_lint_server_url());
}
@Override
public int getBatchSize() {
return projects.size();
}
});
}
}
事務管理是企業級應用程序開發中必不可少的技術, 用來確保數據的完整性和一致性.
事務就是一系列的動作, 它們被當做一個單獨的工作單元. 這些動作要么全部完成, 要么全部不起作用
事務的四個關鍵屬性(ACID)
Spring 既支持編程式事務管理, 也支持聲明式的事務管理.
Spring 還允許簡單地用 @Transactional 注解來標注事務方法.
為了將方法定義為支持事務處理的, 可以為方法添加 @Transactional 注解. 根據 Spring AOP 基于代理機制, 只能標注公有方法.
當事務方法被另一個事務方法調用時, 必須指定事務應該如何傳播. 例如: 方法可能繼續在現有事務中運行, 也可能開啟一個新事務, 并在自己的事務中運行.