Spring葵花宝典

栏目: IT技术 · 发布时间: 4年前

内容简介:一 Spring简介Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架为了解决企业应用开发的复杂性而创建

一 Spring简介

Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架

为了解决企业应用开发的复杂性而创建

二 Spring功能

1. 方便解耦 简化开发

Spring就是一个大工厂 专门负责生成Bean 可以将所有对象创建和依赖关系维护交给Spring管理

2. AOP编程的支持

Spring提供面向切面编程 可以方便的实现对程序进行权限拦截 运行监控等功能

3. 声明式事务的支持

只需要通过配置就可以完成对事务的管理 而无需手动编程

4. 方便程序的测试

Spring对Junit4支持 可以通过注解方便的测试Spring程序

5. 方便集成各种优秀框架

Spring不排斥各种优秀的开源框架 其内部提供了对各种优秀框架的支持

6. 降低JavaEE API的使用难度

对JavaEE开发中一些难用的API(JDBC JavaMail WebService等) 都提供了封装 使这些API应用难度大大降低

三 Spring体系结构

Spring葵花宝典

四 Spring初体验

1. 新建一个Maven项目

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.hy.spring</groupId>
    <artifactId>spring-demo</artifactId>
    <version>1.0-SNAPSHOT</version>

    <!-- 定义依赖版本号 -->
    <properties>
        <junit.version>4.12</junit.version>
        <spring.version>5.0.5.RELEASE</spring.version>
    </properties>

    <!-- 管理jar版本号 -->
    <dependencyManagement>
        <dependencies>
            <!-- junit -->
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>${junit.version}</version>
            </dependency>
            <!-- spring -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-beans</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-webmvc</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-jdbc</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-aspects</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-jms</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context-support</artifactId>
                <version>${spring.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <!-- junit -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
        </dependency>
        <!-- spring -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jms</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <!-- 编译 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.7.0</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

2. 接口

public interface IUserService {

    void insertUser();
}

3. 实现类

public class UserService implements IUserService {

    @Override
    public void insertUser() {
        System.out.println("UserService insert ok");
    }
}

4. 装配Bean resources/beans.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-4.2.xsd">

    <bean id="userService" />
</beans>

5. Spring控制反转创建实例

@Test
public void test01() {
    ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
    IUserService service = (UserService) context.getBean("userService");
    service.insertUser();
}

五 IoC

Inversion of Control 控制反转

将原本在程序中手动创建对象的控制权 交由Spring框架管理

1. xml装配

a. new实现类

<?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-4.2.xsd">

    <!-- 第一种装配方式 new实现类 -->
    <bean id="userService1" />
</beans>

b. 静态工厂方法

public class UserServiceFactory1 {

    public static UserService createUserService() {
        return new UserService();
    }
}
<?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-4.2.xsd">

    <!-- 第二种装配方式 静态工厂方法 -->
    <bean id="userService2" factory-method="createUserService" />
</beans>

c. 实例工厂方法

public class UserServiceFactory2 {

    public UserService createUserService() {
        return new UserService();
    }
}
<?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-4.2.xsd">

    <!-- 第三种装配方式 实例工厂方法 -->
    <bean id="factory2" />
    <bean id="userService3" factory-bean="factory2" factory-method="createUserService" />
</beans>

2. 注解装配

a. 开启注解 配置扫描的位置

<?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-4.2.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd">

    <!-- 开启注解 -->
    <context:annotation-config />

    <!-- 扫描的位置 -->
    <context:component-scan base-package="com.hy.spring" />
</beans>

b. @Component

1> @Component 取代 <bean /> -> ApplicationContext#getBean(Class clazz)

2> @Component("id") 取代 <bean id="" /> -> ApplicationContext#getBean(String id)

3> 在实际Web开发中 提供3个@Component衍生注解(功能一样) 请使用衍生注解

@Repository -> dao层

@Service -> service层

@Controller -> web层

Spring葵花宝典

六 DI

Dependency Injection 依赖注入

在Spring框架负责创建Bean对象时 动态的将依赖对象注入到Bean

1. xml注入

普通数据<value> 引用数据<ref>

a. 属性setter方法注入

<?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-4.2.xsd">

    <bean id="userService" />

    <bean id="userServiceX">
        <!-- 依赖注入数据 调用属性的set方法 -->
        <property name="name" value="nike" />
        <property name="service" ref="userService" />

        <!-- Array -->
        <property name="arg0">
            <array>
                <value>高考</value>
                <value>加油</value>
            </array>
        </property>

        <!-- List -->
        <property name="arg1">
            <list>
                <value>1</value>
                <value>2</value>
                <value>3</value>
            </list>
        </property>

        <!-- Set -->
        <property name="arg2">
            <set>
                <value>1.23</value>
            </set>
        </property>

        <!-- Map -->
        <property name="arg3">
            <map>
                <entry key="age" value="10" />
            </map>
        </property>

        <!-- Properties -->
        <property name="arg4">
            <props>
                <prop key="name">hy</prop>
            </props>
        </property>
    </bean>
</beans>

b. 构造方法注入

<?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-4.2.xsd">

    <bean id="userService" />

    <bean id="userServiceX">
        <!-- 依赖注入数据 通过构造方法 方式一 -->
        <constructor-arg name="name" value="nike" />
        <constructor-arg name="service" ref="userService" />
    </bean>
</beans>
<?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-4.2.xsd">

    <bean id="userService" />

    <bean id="userServiceX">
        <!-- 依赖注入数据 通过构造方法 方式二 -->
        <constructor-arg index="0" value="nike" type="java.lang.String" />
        <constructor-arg index="1" ref="userService" type="com.hy.spring.service.UserService" />
    </bean>
</beans>

c. p命名空间注入

<?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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-4.2.xsd">

    <bean id="userService" />

    <!-- 依赖注入数据 通过p命名空间 -->
    <bean id="userServiceX" p:name="nike" p:service-ref="userService" />
</beans>

2. 注解注入

a. 开启注解 配置扫描的位置

<?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-4.2.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd">

    <!-- 开启注解 -->
    <context:annotation-config />

    <!-- 扫描的位置 -->
    <context:component-scan base-package="com.hy.spring" />
</beans>

b. @Autowired

1> @Autowired -> 自动根据类型注入

2> @Autowired + @Qualifier("id") = @Resource(name = "id") -> 自动根据id注入

Spring葵花宝典

七 加载Spring容器的三种方式

1. 类路径获得配置文件

@Test
public void test01() {
    // 类路径获得配置文件 classes路径 target中查看
    ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
    IUserService service = (UserService) context.getBean("userService");
    System.out.println("IUserService = " + service);
}

2. 文件系统路径获得配置文件

@Test
public void test02() {
    // 文件系统路径获得配置文件 绝对路径
    String path = "//Users/HUANGYI/Desktop/Java/spring-demo/src/main/resources/beans.xml";
    ApplicationContext context = new FileSystemXmlApplicationContext(path);
    IUserService service = (UserService) context.getBean("userService");
    System.out.print("IUserService = " + service);
}

3. BeanFactory 已过时

八 Bean的作用域

resources/beans.xml <bean scope="singleton" /> 或 注解 @Scope("singleton")

1. singleton 默认值 在Spring IoC容器中仅存在一个Bean实例 Bean以单例方式存在

2. prototype 每次从容器中调用Bean时 都返回一个新的实例 即每次调用getBean()时 相当于执行new Bean()

3. request 每次HTTP请求都会创建一个新的Bean 仅适用于WebApplicationContext环境

4. session 同一个Session共享一个Bean 不同Session使用不同Bean 仅适用于WebApplicationContext环境

九 AOP

Aspect Oriented Programming 面向切面

通过预编译方式和运行期动态代理实现程序功能统一维护的一种技术

1. 功能

a. 对业务逻辑各部分进行隔离 从而使业务逻辑各部分之间的耦合度降低 提高程序的可重用性 同时提高了开发效率

b. 采取横向抽取机制 取代了传统纵向继承体系重复性代码

c. 使用纯 Java 实现 不需要专门的编译过程和类加载器 在运行期通过代理方式向目标类织入增强代码

d. 常用于事务管理 性能监视 安全检查 缓存 日志...

2. 实现原理

底层采用代理模式进行实现 有两种实现方式

a. 动态代理(接口代理)

b. CGLIB代理(子类代理)

3. 术语

Target: 目标 需要被代理的类

JoinPoint: 连接点 可能被拦截到的方法

Pointcut: 切入点 已经被增强的连接点

Advice: 通知 增强代码

Weaving: 织入 把通知Advice应用到目标对象Target来创建代理对象Proxy的过程

Proxy: 代理

Aspect: 切面 切入点Pointcut和通知Advice的结合

4. 使用AspectJ进行AOP的开发

AspectJ是一个基于Java语言的AOP框架 Spring2.0开始 Spring引入对AspectJ的支持 AspectJ扩展了Java语言 提供了一个专门的编译器 在编译时提供横向代码的织入 新版本Spring框架 建议使用AspectJ进行AOP的开发

a. xml方式

1> 接口

public interface IUserService {

    void insertUser();

    void deleteUser(int id);

    String selectUser(int id);
}

2> 业务类

public class UserService implements IUserService {

    @Override
    public void insertUser() {
        System.out.println("UserService insert ok");
    }

    @Override
    public void deleteUser(int id) {
        int i = id / 0; //模拟异常
    }

    @Override
    public String selectUser(int id) {
        return "HUANGYI";
    }
}

3> 切面类

public class Aspect {

    /**
     * 前置通知 在方法执行前执行 如果通知抛出异常 阻止方法运行
     * @param joinPoint 连接点
     */
    public void before(JoinPoint joinPoint) {
        System.out.println("前置通知 JoinPoint = " + joinPoint.toString());
    }

    /**
     * 后置通知 方法正常返回后执行 可以获得方法返回值 如果方法中抛出异常 通知无法执行
     * @param joinPoint 连接点
     * @param ret 方法返回值
     */
    public void afterReturning(JoinPoint joinPoint, Object ret) {
        System.out.println("后置通知 ret = " + ret + " JoinPoint = " + joinPoint.toString());
    }

    /**
     * 环绕通知 方法执行前后分别执行 可以阻止方法的执行 必须手动执行目标方法
     * @param proceedingJoinPoint ProceedingJoinPoint
     * @return 方法返回值
     * @throws Throwable 异常
     */
    public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("环绕通知 - 前");
        Object object = proceedingJoinPoint.proceed();
        System.out.println("环绕通知 - 后 ");
        return object + "!!!";
    }

    /**
     * 异常通知 方法抛出异常后执行 如果方法没有抛出异常 无法执行
     * @param joinPoint 连接点
     * @param throwable 异常
     */
    public void afterThrowing(JoinPoint joinPoint, Throwable throwable) {
        System.out.println("异常通知 Throwable = " + throwable.getMessage() + " JoinPoint = " + joinPoint.toString());
    }

    /**
     * 最终通知 方法执行完毕后执行 无论方法中是否出现异常
     * @param joinPoint 连接点
     */
    public void after(JoinPoint joinPoint) {
        System.out.println("最终通知 JoinPoint = " + joinPoint.toString());
    }
}

4> 装配Bean resources/beans.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:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop.xsd">

    <!-- 业务类 -->
    <bean id="userService" />

    <!-- 切面类 -->
    <bean id="aspect" />

    <!-- proxy-target-class true=CGLIB代理 -->
    <aop:config proxy-target-class="true">
        <aop:aspect ref="aspect">
            <!-- expression(表达式): 切点表达式 -->
            <!-- * com.hy.spring.service..*.*(..)
                    * = 任意返回值
                    com.hy.spring.service. = com.hy.spring.service包和所有子包
                    .*.* = .任意类.任意方法名
                    (..) = 任意参数 -->
            <aop:pointcut id="pointcut" expression="execution(* com.hy.spring.service..*.*(..))" />

            <!-- 前置通知 -->
            <aop:before pointcut-ref="pointcut" method="before" />

            <!-- 后置通知 returning ret=方法返回值的参数名 -->
            <aop:after-returning pointcut-ref="pointcut" method="afterReturning" returning="ret" />

            <!-- 环绕通知 -->
            <aop:around pointcut-ref="pointcut" method="around" />

            <!-- 异常通知 throwing throwable=异常的参数名 -->
            <aop:after-throwing pointcut-ref="pointcut" method="afterThrowing" throwing="throwable" />

            <!-- 最终通知 -->
            <aop:after pointcut-ref="pointcut" method="after" />
        </aop:aspect>
    </aop:config>
</beans>

5> 测试

public class XTest {

    @Test
    public void test01() {
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        IUserService service = (IUserService) context.getBean("userService");
        service.insertUser();
    }

    @Test
    public void test02() {
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        IUserService service = (IUserService) context.getBean("userService");
        service.selectUser(1);
    }

    @Test
    public void test03() {
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        IUserService service = (IUserService) context.getBean("userService");
        service.deleteUser(1);
    }
}

b. 注解方式

1> 开启注解 配置扫描的位置

<?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:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd">

    <!-- 开启AOP注解 -->
    <aop:aspectj-autoproxy />

    <!-- 扫描的位置 -->
    <context:component-scan base-package="com.hy.spring" />

    <!-- proxy-target-class true=CGLIB代理 -->
    <aop:config proxy-target-class="true" />
</beans> 

2> 接口

public interface IUserService {

    void insertUser();

    void deleteUser(int id);

    String selectUser(int id);
}

3> 业务类

@Service("userService")
public class UserService implements IUserService {

    @Override
    public void insertUser() {
        System.out.println("UserService insert ok");
    }

    @Override
    public void deleteUser(int id) {
        int i = id / 0; //模拟异常
    }

    @Override
    public String selectUser(int id) {
        return "HUANGYI";
    }
}

4> 切面类

@Component
@org.aspectj.lang.annotation.Aspect
public class Aspect {

    /**
     * 声明公共切入点
     * expression(表达式): 切点表达式
     * * com.hy.spring.service..*.*(..)
     * * = 任意返回值
     * com.hy.spring.service. = com.hy.spring.service包和所有子包
     * .*.* = .任意类.任意方法名
     * (..) = 任意参数
     */
    @Pointcut("execution(* com.hy.spring.service..*.*(..))")
    public void pointcut() {}

    /**
     * 前置通知 在方法执行前执行 如果通知抛出异常 阻止方法运行
     * @param joinPoint 连接点
     */
    @Before("execution(* com.hy.spring.service..*.*(..))")
    public void before(JoinPoint joinPoint) {
        System.out.println("前置通知 JoinPoint = " + joinPoint.toString());
    }

    /**
     * 后置通知 方法正常返回后执行 可以获得方法返回值 如果方法中抛出异常 通知无法执行
     * @param joinPoint 连接点
     * @param ret 方法返回值
     */
    @AfterReturning(value = "pointcut()", returning = "ret")
    public void afterReturning(JoinPoint joinPoint, Object ret) {
        System.out.println("后置通知 ret = " + ret + " JoinPoint = " + joinPoint.toString());
    }

    /**
     * 环绕通知 方法执行前后分别执行 可以阻止方法的执行 必须手动执行目标方法
     * @param proceedingJoinPoint ProceedingJoinPoint
     * @return 方法返回值
     * @throws Throwable 异常
     */
    @Around(value = "pointcut()")
    public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("环绕通知 - 前");
        Object object = proceedingJoinPoint.proceed();
        System.out.println("环绕通知 - 后 ");
        return object + "!!!";
    }

    /**
     * 异常通知 方法抛出异常后执行 如果方法没有抛出异常 无法执行
     * @param joinPoint 连接点
     * @param throwable 异常
     */
    @AfterThrowing(value = "pointcut()", throwing = "throwable")
    public void afterThrowing(JoinPoint joinPoint, Throwable throwable) {
        System.out.println("异常通知 Throwable = " + throwable.getMessage() + " JoinPoint = " + joinPoint.toString());
    }

    /**
     * 最终通知 方法执行完毕后执行 无论方法中是否出现异常
     * @param joinPoint 连接点
     */
    @After(value = "pointcut()")
    public void after(JoinPoint joinPoint) {
        System.out.println("最终通知 JoinPoint = " + joinPoint.toString());
    }
}

5> 测试

public class XTest {

    @Test
    public void test01() {
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        IUserService service = (IUserService) context.getBean("userService");
        service.insertUser();
    }

    @Test
    public void test02() {
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        IUserService service = (IUserService) context.getBean("userService");
        service.selectUser(1);
    }

    @Test
    public void test03() {
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        IUserService service = (IUserService) context.getBean("userService");
        service.deleteUser(1);
    }
}

5. 使用AOP进行事务配置 框架整合时讲解


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

C语言入门经典

C语言入门经典

霍顿 (Ivor Horton) / 清华大学出版社 / 2008-4-1 / 69.80元

本书是编程语言先驱者Ivor Horton的经典之作,是C语言方面最畅销的图书品种之一。本书集综合性、实用性为一体,是学习C语言的优秀入门教材,在世界范围内广受欢迎,口碑极佳。书中除了讲解C程序设计语言,还广泛介绍了作为一名C程序设计人员应该掌握的必要知识,并提供了大量的实用性很强的编程实例。本书的目标是使你在C语言程序设计方面由一位初学者成为一位称职的程序员。读者基本不需要具备任何编程知识,即可......一起来看看 《C语言入门经典》 这本书的介绍吧!

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

html转js在线工具
html转js在线工具

html转js在线工具

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具