终于到了实验三,吐槽一句,环境不一致真的很难受,又不想用Eclipse,还不想重写一份,这真的是很难办的事情呢。🙄

1. 完成PersistService和SelectService这两个实现类中所有方法,定义他们的抽象父类,并抽象出公共方法,且用到枚举。

有可能我看漏了,或者理解错报告要求的意思了,先这么做吧。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

// persistService
@Override
public void updateStudent(StudentModel t, Integer id) {
try {
if (!super.checkWhitePermission(id)) {
String string = String.format("记录%s无法更新", id);
logger.warn(string);
}

studentMapper.updateStudent(t, id);
logger.info("记录" + id + "已经更新");

} catch (Exception e) {
logger.error("Error", e);
}
}

// studentMapperTest
@Test
public void testUpdateStudent() {
StudentModel studentModel = new StudentModel("王五", "女", "软件二班", 1, 60 ,60 ,60, 60);
persistService.updateStudent(studentModel, 1);
logger.info("更新成功");
}

没看到SelectService类里有其它需要实现的类,也看了其继承的类和接口,同样都被实现过了。

定义他们的抽象父类,并抽象出公共方法,且用到枚举,这几句话想了好久,没搞懂什么意思,虽然这两个类都有在对StudentModel做事情,但是区分度已经很大了哇,没搞懂还能抽出什么公共方法,但是看到了后边说 且需要用到枚举 ,难道是要把这几个对StudentModel操作的方法都统一到一个父类里,然后根据父类里的type类型枚举去判断当前子类是否有“权限”去执行这个方法?思来想去,还是没搞懂是啥意思。待做求解。

2. 验证课堂上AOP的相关样例代码,编写在自己业务场景下的面向切面程序,包括before,after,around,After-Returning这四种通知。

自己觉得Spring AOP有用到了类似JVM的runtime内容(存粹自己的猜测,没有查阅过相关资料),在运行时做了替换,比如说AABB类在执行method()之前,通过AOP的配置文件表明是用哪个类的哪个方法在哪些类的哪些方法运行前、后等时期先执行,这点跟OC中的Runtime思路非常的类似,使用AOP可以有两种做法,一是通过AOP类使用java注解的方式表明,另外一种是在Spring配置文件中写明是哪个类的哪个方法需要在什么地方被执行,经过一番折腾下来,个人觉得使用Spring配置文件写明切面函数的调用比较好。

老师一直想让我们编写自己的业务场景,自己的业务场景,但是落实到实处就是想要去验证AOP是你自己写的嘛,emmm,那就上demo程序好了。

  1. 创建Spring工程,导入额外的aopalliance.jaraspectjweaver

  2. 创建User类;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class User {

private Integer id;
private String nickname;

public Integer getId() {
return id;
}

public void setId(Integer id) {
this.id = id;
}

public String getNickname() {
return nickname;
}

public void setNickname(String nickname) {
this.nickname = nickname;
}
}

  1. 创建UserMapper类,可以不用手撸SQL,让Mybatis去做:
1
2
3
4
5
6
7
8
import java.util.List;

public interface UserMapper {

public User selectUserWithID(int ID) throws Exception;

}

  1. 创建selectUserAdvice类,里边包含了对User类进行操作的所有切面程序:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    public class userAdvice {

    public void userSayHello() {
    System.out.println("user say hello!");
    }

    public void userSayBay() {
    System.out.println("user say bay!");
    }

    public void userSaySee() {
    System.out.println("user say see!");
    }

    public void userSayUser(User user) {
    System.out.println("user say " + user.nickname);
    }

    }

  2. 配置User.xml,供MyBatis操作user表:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

    <mapper namespace="com.pjhubs.UserMapper">
    <select id="selectUserWithID" parameterType="int" resultType="com.pjhubs.User">
    select * from user where id = #{id}
    </select>
    </mapper>

  3. 配置SqlMapConfig.xml,MyBatis的配置文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=false"/>
<property name="username" value="your DB name"/>
<property name="password" value="your DB password"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="User.xml"/>
</mappers>
</configuration>

  1. 创建Spring配置文件(intelliJ在创建Spring工程的时候可进行勾选协助创建),并写下,(参考实验文档中内容):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:task="http://www.springframework.org/schema/task" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:util="http://www.springframework.org/schema/util" xmlns:p="http://www.springframework.org/schema/p"
    xmlns:cache="http://www.springframework.org/schema/cache"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
    http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd
    http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd
    http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd">


    <bean id="user" class="com.pjhubs.user" />
    <bean id="userAdvice" class="com.pjhubs.userAdvice" />

    <aop:config proxy-target-class="true">
    <aop:pointcut id="selectUser" expression="target(com.pjhubs.user) and execution(* select*(..))" />
    <aop:aspect id="userAdvice" ref="userAdvice">
    <aop:before method="userSayHello" pointcut-ref="selectUser" />
    <aop:around method="userSayBay" pointcut-ref="selectUser" />
    <aop:after method="userSaySee" pointcut-ref="selectUser" />
    <aop:after-returning method="userSayUser" pointcut-ref="selectUser" returning="bindParam" />
    </aop:aspect>
    </aop:config>

    </beans>

  2. 测试。同时也在做第三题——(利用Spring框架的单元测试跑通以上所有方法。),因为我们已经引入了Spring,所以就不要再只是使用JUnit啦~需要同时引入以下jar包,

  • JUnit4
  • Spring-Test
    本着赶紧做完的心态,并没有使用Maven等依赖工具对java工程的各种依赖包进行管理🙂,所以每次都会对其手动添加jar包。emmm。创建测试类userTest:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("/spring-config.xml")

public class userTest() {
@Resource
public User user;

@Test
public void testSelectUser() {
User user = userMapper.selectUserWithID(2);
System.out.println("id:" + user.getId() + " 昵称:" + user.getNickname());
}
}

如果你嫌弃上边说的太啰嗦,那么这还有个简约版的。

首先在intelliJ下创建一个Spring工程,当然要你的intelliJ是社区版的就算了,功能支持的受限。记得勾选创建默认的Spring XML配置文件。

验证IOC相关内容,随意创建一个类,在其中随意写下一个方法,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class IOCTest {

private String IOCName;


public String getIOCName() {
return IOCName;
}

public void setIOCName(String IOCName) {
this.IOCName = IOCName;
}

public void printIOCName() {
System.out.println(IOCName);
}
}

  1. 在工程默认生成的Spring XML配置文件中,新增,

    1
    2
    3
    <bean id="IOCTest" class="IOCTest">
    <property name="IOCName" value="pjhubs"></property>
    </bean>
  2. 在Main类中或者新建一个测试类的测试方法,在该方法中写下,

1
2
3
4
5
6
7
public class Main {
public static void main(String[] args) {
ApplicationContext context=new ClassPathXmlApplicationContext("spring-config.xml");
IOCTest iocTest = (IOCTest)context.getBean("IOCTest");
iocTest.printIOCName();
}
}

这样就完成了IOC的内容,把创建对象的能力“转移”掉了,同时也达到了我们只需要定义接口,相关类的控制交由IOC管理即可,而且当我们有需要对两个类定义关系时,只需要在配置文件中定义好即可。

验证AOC的相关内容

  1. 创建好工程后,在这个地址下载aspectjweaver包,导入工程。

  2. 分别创建两个类,本次我们采用XML文件配置的方式来做AOP,如下所示,

    1
    2
    3
    4
    5
    6
    7
    8
    public class AOPTest {

    public void AOPTest() {
    System.out.println("AOPTest......");
    }

    }

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29

    import org.aspectj.lang.ProceedingJoinPoint;

    public class AOPMethon {

    //前置增强
    public void before(){
    System.out.println("前置增强........");
    }

    //后置增强
    public void after(){
    System.out.println("后置增强........");
    }

    //环绕增强
    public void arround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
    //方法之前执行的代码
    System.out.println("环绕增强 方法之前执行........");

    //执行被增强的方法
    proceedingJoinPoint.proceed();

    //方法之后执行的代码
    System.out.println("环绕增强 方法之后执行........");
    }

    }

  3. 修改Spring XML配置文件为,

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    <?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.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

    <!--1 配置对象-->
    <bean class="AOPMethon" id="AOPMethon"></bean>
    <bean class="AOPTest" id="AOPTest"></bean>

    <!--2 配置AOP操作-->
    <aop:config>
    <!--配置切入点-->
    <aop:pointcut id="pointcut" expression="execution(* AOPTest.AOPTest())"/>
    <!--配置切面
    把增强用到方法上面
    -->
    <aop:aspect ref="AOPMethon">
    <!--前置增强-->
    <aop:before method="before" pointcut-ref="pointcut"/>

    <!--后置增强-->
    <aop:after-returning method="after" pointcut-ref="pointcut"/>

    <!--环绕增强-->
    <aop:around method="arround" pointcut-ref="pointcut"/>
    </aop:aspect>
    </aop:config>

    </beans>
  4. 新建一个测试类,写下相关的测试方法,

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    	import org.junit.Test;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;

    public class test {
    @Test
    public void AOPTest() {
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-config.xml");
    AOPTest aopTest = (AOPTest) applicationContext.getBean("AOPTest");
    aopTest.AOPTest();
    }
    }

  5. 输出的结果为:

    1
    2
    3
    4
    5
    前置增强........
    环绕增强 方法之前执行........
    AOPTest......
    环绕增强 方法之后执行........
    后置增强........

至于AOP中的这几个增强方法的区别,就不展开啦~~~