注解配置
当我们的项目越来越复杂时,配置文件也会变得复杂
影响开发效率
所以 Spring 提供了注解方式来配置 bean
准备工作
使用注解准备工作
1.添加 Context 命名空间
xmlns:context="http://www.springframework.org/schema/context"
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-4.3.xsd"
2.添加 aop jar 包 spring-aop-5.0.5.RELEASE.jar
3.扫描注解
<context:component-scan base-package="需要扫描的包的包名"></context:component-scan>
注解详细
1.@Component
例如:给Person 类加上该注解等同于在配置文件中添加了"person" class="com.xxx.entity.Person">
如果没有指定 bean 名字,默认是类名以小写开头
指定名字:@Component("name")
2.@Component 的衍生标签
@Service 对应 Service 业务逻辑层
@Controller 对应 Action/Servlet
@Repository 对应数据库相关(Dao)
这三个子标签作用和 @Component 一样,但是更加语义化,更符合 JavaEES 分层思想
3.@Scope 用来控制 bean 的作用域
@Scope(scopeName="singleton")
@Scope(scopeName="prototype")
@Scope(scopeName="request")
@Scope(scopeName="session")
4.注入属性
@Value("值")
可以写在属性上,但是会破坏对象的封装性(建议写在 set 方法上)
@Value("(*^__^*) 嘻嘻……")
private String name;
可以写在 set 方法上
@Value("男")
public void setGender(String gender) {
this.gender = gender;
}
5.@Autowired 自动装配,可以将容器中对应 bean 自动注入到属性中
@Qualifier 如果容器中有多个对应类型的 bean, 可以使用@Qualifier指定具体注入哪一个
和 @Autowired 搭配使用
6.@Resource 手动装配,告诉 Spring, 注入哪个 bean
@Resource(name = "myHouse")
7.@PostConstruct 对象构造后立即执行
8.@PreDestroy 对象销毁前执行
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class Person {
@Value("(*^__^*) 嘻嘻……")
private String name;
private String gender;
private Integer age;
@Resource(name = "myHouse")
private House house;
public Person() {
super();
System.out.println("无参");
}
public Person(String name, String gender, Integer age) {
super();
System.out.println("有参");
this.name = name;
this.gender = gender;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getGender() {
return gender;
}
@Value("男")
public void setGender(String gender) {
this.gender = gender;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public House getHouse() {
return house;
}
public void setHouse(House house) {
this.house = house;
}
@Override
public String toString() {
return "Person [name=" + name + ", gender=" + gender + ", age=" + age + ", house=" + house + "]";
}
@PostConstruct
public void init() {
System.out.println("前置方法");
}
@PreDestroy
public void destroy() {
System.out.println("后置方法");
}
}
Spring 与 Junit 整合测试
在测试环境需要手动创建 Spring 容器 管理生命周期
SpringTest 就是为了方便在测试环境获取容器出现的
1.导入 jar 包
2.在测试类上添加
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class SpringTest {
@Resource(name="person")
Person person;
@Test
public void method() {
System.out.println(person);
}
}
Test 环境和 Web 环境的区别
Test 不会自动创建容器,所以无法使用 @Autowired
Web 环境中 Spring 可以跟随项目启动
AOP
AOP Aspect Oriented Programming
全程面向切面编程,是一种编程思想,就像 OOP 一样
OOP 的核心就是类和对象
AOP 的核心就是切面
其实 AOP 说的简单点就是讲公共代码进行抽取
集中编写
例如:使用过得过滤器,拦截器,都是 AOP 思想
AOP名词解释
Joinpoint连接点 可以增强对象
Pointcut切入点 需要进行增强方法
Advice 通知、增强代码
Target 目标对象 被代理对象
Weaving 织入 将通知应用到链接点的过程
代理 代理对象
切面 切入点+通知
Spring 实现 AOP 原理
1.动态代理
A 对象需要被代理
B 对象来代理 A
本来直接调用 A 对象的方法
现在换个方式先调用 B 对象,然后 B 对象再去调用 A 对象
被代理对象 A 必须有实现某个接口
注意:没有实现任何接口的对象无法代理
2.cglib
A 对象需要被代理
实现代码增强的原理
会自动生成被代理类的子类对象
生成一个 A 类对象的子类
在子类中对代码进行增强
然后调用父类的原有代码
注意:被 final 修饰的类不能被代理,不能进行增强
如果某个类即没有接口,又被 final 修饰 SpringAOP 就搞不定了
这时 AspectJ 发挥作用了