控制反转(IOC)
分为控制和反转
控制:对象的创建交给了spring容器,在spring创建对象的过程中会根据 bean来创建对象,也可以说一个bean就是一个对象
反转:主动权由程序员交给了用户,用户可以选择调用;传统的是 在程序中使用new来创建对象然后使用对象调用方法, 现为 spring容器创建对象然后传入对象,不需要更改原程序,原程序只使用传入的对象(此种方式在springboot中非常常见,如重写拦截器)
也叫依赖注入,即将 需要生成对象的类 注入,由spring容器自动创建,创建实例的方式,是通过反射的方式获取类,然后实例化后注入
xml配置方式
1 2 3 4 5
| public interface UserService {
public void origdothings();
}
|
1 2 3 4 5 6 7
| public class UserServiceImp implements UserService{ public void origdothings() { System.out.println("这是原本要做的事"); } }
|
1 2 3 4 5 6 7 8 9 10
| <?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.xsd">
<bean id="service" class="com.simplemw.service.UserServiceImp"/> </beans>
|
1 2 3 4 5 6 7 8 9 10 11
| public class MyTest {
public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); UserService userService = (UserService) context.getBean("service"); userService.origdothings(); }
}
|
注解配置方式
1 2 3 4 5
| public interface UserService {
public void origdothings();
}
|
1 2 3 4 5 6 7 8 9
| @Component("userservice") public class UserServiceImp implements UserService{
public void origdothings() { System.out.println("这是原本要做的事"); }
}
|
1 2 3 4 5 6 7 8 9 10
| <?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.xsd">
<context:component-scan base-package="com.simplemw.service"></context:component-scan> </beans>
|
1 2 3 4 5 6 7 8 9 10 11
| public class MyTest {
public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); UserService userService = (UserService) context.getBean("service"); userService.origdothings(); }
}
|
面向切面编程(AOP)
解释:在不改变原有代码轨迹的基础上给其添加一些额外的功能 如日志打印等
xml配置方式
1 2 3 4 5
| public interface UserService {
public void origdothings();
}
|
1 2 3 4 5 6 7
| public class UserServiceImp implements UserService{ public void origdothings() { System.out.println("这是原本要做的事"); } }
|
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
| public class AddThings {
public void before(){ System.out.println("之前做的事"); }
public void after(){ System.out.println("之后做的事"); }
public void around(ProceedingJoinPoint pjp) throws Throwable { System.out.println("环绕前做的事"); pjp.proceed(); System.out.println("环绕后做的事"); }
public void after_return(){ System.out.println("方法完成后的通知"); }
public void after_throwing(){ System.out.println("方法抛出后的通知"); } }
|
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 31 32 33 34 35
| <?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">
<bean id="service" class="com.simplemw.service.UserServiceImp"/> <bean id="add" class="com.simplemw.add.AddThings"/>
<aop:config> <aop:aspect ref="add"> <aop:pointcut id="point" expression="execution(* com.simplemw.service.UserServiceImp.*(..))"/> <aop:before method="before" pointcut-ref="point"/> <aop:after method="after" pointcut-ref="point"/> <aop:around method="around" pointcut-ref="point"/> <aop:after-returning method="after_return" pointcut-ref="point"/> <aop:after-throwing method="after_throwing" pointcut-ref="point"/> </aop:aspect> </aop:config> </beans>
|
1 2 3 4 5 6 7 8 9 10 11 12
| public class MyTest {
public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); UserService userService = (UserService) context.getBean("service"); userService.origdothings(); }
}
|
1 2 3 4 5 6 7
| 之前做的事 环绕前做的事 这是原本要做的事 方法完成后的通知 环绕后做的事 之后做的事
|
注:此种方式,添加的功能顺序与配置顺序有关,即先配置环绕和后配置环绕,输出结果不同
注解配置方式
1 2 3 4 5 6
| public interface UserService {
public void origdothings();
}
|
1 2 3 4 5 6 7 8 9 10
| @Component("userservice") public class UserServiceImp implements UserService{
public void origdothings() { System.out.println("这是原本要做的事"); }
}
|
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| @Component
@Aspect public class AnnotationPoint {
@Pointcut("execution(* com.simplemw.service.UserServiceImp.*(..))") public void point(){}
@Before("point()") public void before(){ System.out.println("之前做的事"); }
@After("point()") public void after(){ System.out.println("之后做的事"); } @Around("point()") public void around(ProceedingJoinPoint pjp) throws Throwable { System.out.println("环绕前做的事"); pjp.proceed(); System.out.println("环绕后做的事"); } @AfterReturning("point()") public void after_return(){ System.out.println("方法完成后的通知"); } @AfterThrowing("point()") public void after_throwing(){ System.out.println("方法抛出后的通知"); }
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| <?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" 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/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<context:component-scan base-package="com.simplemw"></context:component-scan>
<aop:aspectj-autoproxy/>
</beans>
|
1 2 3 4 5 6 7 8 9 10
| public class MyTest {
public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); UserService userService = (UserService) context.getBean("userservice"); userService.origdothings(); }
}
|
1 2 3 4 5 6 7
| 环绕前做的事 之前做的事 这是原本要做的事 方法完成后的通知 之后做的事 环绕后做的事
|
注:此种方式与xml配置方式不同,插入功能顺序与配置顺序无关
xml配置方式和注解配置方式可以混用
自定义注解方式
1 2 3 4 5 6
| @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD}) public @interface MyLabel {
String value() default ""; }
|
1 2 3 4 5 6
| @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD}) public @interface MyLabelTwo {
String value() default ""; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| @Component @Aspect public class AopConfig {
@Before(value = "@annotation(myLabel1)") public void before(MyLabel myLabel1){ TestService.str = myLabel1.value(); }
@Pointcut(value = "@annotation(myLabel2)") public void myPointCut(MyLabelTwo myLabel2){
}
@Before(value = "myPointCut(myLabel2)") public void beforeTwo(MyLabelTwo myLabel2){ TestService.str = myLabel2.value(); }
}
|
1 2 3 4 5 6 7 8 9 10 11
| public static String str = "原始的字符串";
@MyLabel("第一次传入字符串") public void function(){
}
@MyLabelTwo("第二次传入字符串") public void function1(String str){
}
|
1 2 3 4 5 6 7 8 9 10 11 12
| @Autowired private TestService testService;
@GetMapping("/ces") public String getString(){ testService.function(); System.out.println(TestService.str); testService.function1("这是第二次"); System.out.println(TestService.str); return TestService.str; }
|