Spring IOC
概念说明
Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器(框架)。
控制反转IoC
控制反转IoC(Inversion of Control),是一种设计思想,DI(依赖注入)是实现IoC的一种方法,也有人认为DI只是IoC的另一种说法。没有IoC的程序中 , 我们使用面向对象编程 , 对象的创建与对象间的依赖关系完全硬编码在程序中,对象的创建由程序自己控制,控制反转后将对象的创建转移给第三方,个人认为所谓控制反转就是:获得依赖对象的方式反转了。
实现方式:
1、xml配置方式
2、注解方式
Spring IOC xml配置实现
xml 配置文件
<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="student" class="com.msb.bean.Student" >
<property name="name" value="夏明"/>
<property name="age" value="18"/>
</bean>
<bean id="card" class="com.msb.bean.Card" scope="prototype"/>
<bean id="test" class="com.msb.aop.AopTest"></bean>
<bean id="before" class="com.msb.aop.AopAdvice"></bean>
</beans>
要被实例化的对象:
package com.msb.bean;
public class Card {
}
package com.msb.bean;
import lombok.ToString;
@ToString
public class Student {
String name;
int age;
Card card;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String say(String test){
System.out.println("我是:"+name+",我都是学生:"+test);
return test;
}
@Deprecated
public void test(){
System.out.println("我是过时方法");
}
}
main主函数
package com.springtest.net;
import com.springtest.net.bean.Student;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Main {
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("test.xml");
Student student = (Student) context.getBean("student");
student.say("foamy");
}
}
Spring IOC 注解实现
注解方法一:
pom.xml
<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.msb</groupId>
<artifactId>spring_test</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>spring_test</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.29</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.3.29</version>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.10.1</version>
<configuration>
<compilerArgs>
<arg>-parameters</arg>
</compilerArgs>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
class对象
package com.msb.bean;
public class Card {
}
package com.msb.bean;
public class Card {
}
package com.msb.bean;
import lombok.ToString;
@ToString
public class Student {
String name;
int age;
Card card;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String say(String test){
System.out.println("我是:"+name+",我都是学生:"+test);
return test;
}
@Deprecated
public void test(){
System.out.println("我是过时方法");
}
}
package com.msb.config;
import com.msb.bean.Card;
import com.msb.bean.Student;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Bean;
@Configuration
public class MainConfiguration {
@Bean
public Card card(){
return new Card();
}
@Bean
public Student student() {
Student student = new Student();
student.setName("小明");
return student;
}
}
main 主函数
package com.msb;
import com.msb.bean.Student;
import com.msb.config.MainConfiguration;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Main
{
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfiguration.class);
Student student = (Student) context.getBean("student");
System.out.println(student);
}
}
注解方法二:
1、在MainConfiguration 方法上增加注解@ComponentScan(“com.msb.bean”) 定义扫描范围,且这个类中不用配置@Bean对应对象;
2、在com.msb.bean 需要被实例化的的方法上增加@Component
注解方法三:
1、在MainConfiguration 方法上增加注解@ComponentScan(“com.msb.bean”) 定义扫描范围,且这个类中不用配置@Bean对应对象;
2、在com.msb.bean 需要被实例化的的方法上增加@Component;
3、Student 中的Card card,上面@Resource @Autowired 可以互换;
4、@Resource 也可以增加在set方法上
@Resource
student可以改为:
package com.msb.bean;
import lombok.ToString;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
@ToString
@Component
public class Student {
String name;
int age;
@Resource
Card card;
}
Card可以改为
package com.msb.bean;
import org.springframework.stereotype.Component;
import org.springframework.context.annotation.Scope;
//@Component
@Component
//@Scope
@Scope("prototype")
public class Card {
}
注解方法四:
通过 @Autowired @Qualifier(“mont”)名字注入
如果是: @Qualifier(“mont”)
如果是 @Qualifier(“sun”)
注解方法五:
如果Bean是在配置文件中进行定义的,我们还可以在方法的参数中使用@Autowired来进行自动注入:
@ComponentScan("com.test.bean")
@Configuration
public class MainConfiguration {
@Bean
public Student student(@Autowired Card card){
Student student = new Student();
student.setCard(card);
return student;
}
}
这个我也没有理解
Spring AOP
Spring AOP xml配置实现
Spring IOC xml配置实现 的基础上做的增加
package com.springtest.net.Aop;
import org.springframework.aop.MethodBeforeAdvice;
import java.lang.reflect.Method;
import java.util.Arrays;
public class AopAdvice implements MethodBeforeAdvice {
@Override
public void before(Method method, Object[] args, Object target) throws Throwable {
System.out.println("方法名称:"+method.getName());
System.out.println("方法参数:"+ Arrays.toString(args));
System.out.println("方法执行的对象"+target);
}
}
package com.springtest.net.Aop;
import lombok.extern.java.Log;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
@Log
public class AopTest {
public void before(){
log.info("我是方法执行之前的日志");
}
public void after(JoinPoint point){
log.info("我是方法执行之后的日志");
}
public Object around(ProceedingJoinPoint joinPoint) throws Throwable{
log.info("我是前置方法!");
Object res = joinPoint.proceed();
log.info("我是环绕方法!");
return res;
}
}
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.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="student" class="com.springtest.net.bean.Student">
<property name="name" value="小明"/>
<property name="age" value="18"/>
<property name="card" ref="card"/>
</bean>
<bean id="card" class="com.springtest.net.bean.Card" scope="prototype"/>
<bean id="test" class="com.springtest.net.Aop.AopTest"></bean>
<bean id="before" class="com.springtest.net.Aop.AopAdvice"></bean>
<aop:config>
<aop:aspect ref = "test">
<aop:pointcut id="stu" expression="execution(* com.springtest.net.bean.Student.say(String))"/>
<aop:around method="around" pointcut-ref="stu"/>
</aop:aspect>
<!--<aop:pointcut id="stu" expression="execution(* com.springtest.net.bean.Student.say(String))"/>-->
<!--<aop:advisor advice-ref="before" pointcut-ref="stu"/>-->
</aop:config>
</beans>
Spring AOP 注解实现
1、@Component //定义为一个bean 配置在要被定义为一个切面的对象上面
2、@Aspect //定义为一个切面
3、 @Before(“execution(* com.msb.bean.Student.say(…))”) 定义切面的类型
@AfterReturning(“execution(* com.msb.bean.Student.say(…))”)
环绕方法
@Around("execution(* com.msb.bean.Student.say(..))")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable{
log.info("我是前置方法!");
Object res = joinPoint.proceed();
log.info("我是环绕方法!");
return res;
}
aop
package com.msb.aop;
import lombok.extern.java.Log;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
@Log
@Component //定义为一个bean
@Aspect //定义为一个贴面
public class AopTest {
@Before("execution(* com.msb.bean.Student.say(..))")
public void before(){
log.info("我是方法执行之前的日志");
}
@AfterReturning("execution(* com.msb.bean.Student.say(..))")
public void after(JoinPoint point){
log.info("我是方法执行之后的日志");
}
public Object around(ProceedingJoinPoint joinPoint) throws Throwable{
log.info("我是前置方法!");
Object res = joinPoint.proceed();
log.info("我是环绕方法!");
return res;
}
}
bean
package com.msb.bean;
import lombok.ToString;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
@ToString
@Component
public class Student {
String name;
int age;
Card card;
@Autowired
@Qualifier("sun")
public void setCard(Card card) {
// System.out.println("我是set注解");
this.card = card;
}
public String say(String text){
System.out.println("我叫");
return text;
}
}
package com.msb.bean;
import org.springframework.stereotype.Component;
import org.springframework.context.annotation.Scope;
@Component("sun")
@Scope("prototype")
public class Card {
}
config
package com.msb.config;
import com.msb.bean.Card;
import com.msb.bean.Student;
import org.springframework.context.annotation.*;
@EnableAspectJAutoProxy //AOP 在程序运行时动态的将代码切入到指定的类的指定的方法上。
@Configuration
@ComponentScans({@ComponentScan("com.msb.bean"),@ComponentScan("com.msb.aop")})
public class MainConfiguration {
// @Bean("mont")
// public Card card(){
// return new Card();
// }
// @Bean
// public Student student() {
// Student student = new Student();
// student.setName("小明");
// return student;
// }
}
main
package com.msb;
import com.msb.bean.Student;
import com.msb.config.MainConfiguration;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Main
{
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfiguration.class);
Student student = context.getBean(Student.class);
// System.out.println(student)
student.say("foamy");
}
}
说明:
1、@Import(Teacher.class) 直接将对象注册为bean
2、@Import(TestConfiguration.class) 引入另一个配置文件例如;
新的对象:
package com.msb.bean;
public class Teacher {
public void teacher(){
}
}
新的注解配置文件
package com.msb.config;
import com.msb.bean.Teacher;
import org.springframework.context.annotation.Bean;
public class TestConfiguration {
@Bean
public Teacher teacher(){
return new Teacher();
}
}