1.注解方式实现IoC
除了使用xml配置文件实现IoC外,Spring还提供了注解的方式实现IoC。相比于xml文件,注解方式开发更加方便。
需要引入context的约束,具体的约束如下
开启注解扫描:
base-package表示要扫描的包结构。com.mq表示扫描com.mq包结构下的所有文件。
@Component(value="myService")
public class MyServiceImpl implements MyService {
private MydaoImpl myDao;
private String name;
private int age;
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public void setMyDao(MydaoImpl myDao) {
this.myDao = myDao;
}
@Override
public void saveUser() {
System.out.println("业务层保存用户");
}
public void printInfo(){
System.out.println("age-"+age+"name-"+name);
}
public void testDI(){
myDao.save();
}
}
@Test
public void f1(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
MyServiceImpl userService = (MyServiceImpl) applicationContext.getBean("myService");
userService.saveUser();
}
11:07:44,255 INFO ClassPathXmlApplicationContext:578 - Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@4f4a7090: startup date [Sat Jul 15 11:07:44 CST 2017]; root of context hierarchy
11:07:44,382 INFO XmlBeanDefinitionReader:317 - Loading XML bean definitions from class path resource [applicationContext.xml]
业务层保存用户
@Component(value="myService") -- 相当于在XML的配置方式中 @Repository(value="myDao")
public class MydaoImpl implements Mydao {
public void save() {
System.out.println("这里是持久层");
}
}
这里MydaoImpl就使用了@Repository注解,本质上和
@Componen是一样的。
@Component(value="myService")
public class MyServiceImpl implements MyService {
@Resource(name="myDao")
private MydaoImpl myDao;
@Value(value="曹操")
private String name;
@Value(value="45")
private int age;
@Value(value="45")
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public void setMyDao(MydaoImpl myDao) {
this.myDao = myDao;
}
@Override
public void saveUser() {
System.out.println("业务层保存用户");
}
public void printInfo(){
System.out.println("age-"+age+"name-"+name);
}
public void testDI(){
myDao.save();
}
}
通过@Resource进行类属性的注入。
@Test
public void f1(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
MyServiceImpl userService = (MyServiceImpl) applicationContext.getBean("myService");
userService.saveUser();
userService.printInfo();
userService.testDI();
}
11:32:40,947 INFO ClassPathXmlApplicationContext:578 - Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@4f4a7090: startup date [Sat Jul 15 11:32:40 CST 2017]; root of context hierarchy
11:32:41,116 INFO XmlBeanDefinitionReader:317 - Loading XML bean definitions from class path resource [applicationContext.xml]
业务层保存用户
age-45name-45
这里是持久层
2.Spring框架整合JUnit单元测试
首先需要引入spring-test.jar包。
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class MyTest {
@Resource(name="myService")
private MyServiceImpl userService;
@Test
public void f2(){
userService.saveUser();
userService.printInfo();
userService.testDI();
}
}
业务层保存用户
age-45name-45
这里是持久层
需要添加三个注解,"classpath:applicationContext.xml"表示类路径下的
applicationContext.xml文件,名称也必须要保持一致。
3.AOP
public class MyAspect {
public void writeLog(){
System.out.println("正在生成日志");
}
}
需要被增强的方法
public class MyServiceImpl implements MyService {
@Override
public void saveUser() {
System.out.println("业务层保存用户");
}
}
正在生成日志
业务层保存用户
13:19:19,589 INFO GenericApplicationContext:960 - Closing org.springframework.context.support.GenericApplicationContext@1810399e: startup date [Sat Jul 15 13:19:19 CST 2017]; root of context hierarchy
1. 前置通知
* 在目标类的方法执行之前执行。
* 配置文件信息:
* 应用:可以对方法的参数来做校验
2. 最终通知
* 在目标类的方法执行之后执行,如果程序出现了异常,最终通知也会执行。
* 在配置文件中编写具体的配置:
* 应用:例如像释放资源
3. 后置通知
* 方法正常执行后的通知。
* 在配置文件中编写具体的配置:
* 应用:可以修改方法的返回值
4. 异常抛出通知
* 在抛出异常后通知
* 在配置文件中编写具体的配置:
* 应用:包装异常的信息
5. 环绕通知
* 方法的执行前后执行。
* 在配置文件中编写具体的配置:saveUser
"/>
* 要注意:目标的方法默认不执行,需要使用ProceedingJoinPoint对来让目标对象的方法执行。
public class MyAspect {
public void writeLog(){
System.out.println("正在生成日志");
}
/**
* 环绕通知:方法执行之前和方法执行之后进行通知,默认的情况下,目标对象的方法不能执行的。需要手动让目标对象的方法执行
*/
public void writeLog2(ProceedingJoinPoint joinPoint){
System.out.println("生成日志前...");
try {
// 手动让目标对象的方法去执行
joinPoint.proceed();
} catch (Throwable e) {
e.printStackTrace();
}
System.out.println("生成日志后...");
}
}
需要被增强的方法依然是saveUser方法。
执行结果:
生成日志前...
业务层保存用户
生成日志后...
13:40:25,462 INFO GenericApplicationContext:960 - Closing org.springframework.context.support.GenericApplicationContext@1810399e: startup date [Sat Jul 15 13:40:24 CST 2017]; root of context hierarchy
1. 在配置切入点的时候,需要定义表达式,重点的格式如下:execution(public * *(..)),具体展开如下:
* 切入点表达式的格式如下:
* execution([修饰符] 返回值类型 包名.类名.方法名(参数))
* 修饰符可以省略不写,不是必须要出现的。
* 返回值类型是不能省略不写的,根据你的方法来编写返回值。可以使用 * 代替。
* 包名例如:com.itheima.demo3.BookDaoImpl
* 首先com是不能省略不写的,但是可以使用 * 代替
* 中间的包名可以使用 * 号代替
* 如果想省略中间的包名可以使用 ..
* 类名也可以使用 * 号代替,也有类似的写法:*DaoImpl
* 方法也可以使用 * 号代替
* 参数如果是一个参数可以使用 * 号代替,如果想代表任意参数使用 ..