* 目录 *
bean管理——注解方式
1. 基本涵义
- 注解:代码里面特殊的标记,使用注解可以完成一些功能
- 表示形式:@+注解名称(属性名称/属性值)例如:@Test
- 使用范围:属性,方法,类上都可以
2. 注解创建对象
(1)创建对象的4个注解:
名称 | 应用 |
---|---|
@Component | |
@Controller | web层 |
@Service | 业务层 |
@Repository | 持久层 |
【目前功能都一样,用来创建对象。】
* 创建对象的单实例和双实例
@默认情况下 —— 单实例
@Scope(value = “prototype”) —— 多实例
(2)准备步骤:.创建新项目;导入相关jar包(Spring的基本jar包+日志jar包+aop包;)
简单入门,具体操作:写配置文件,引入context约束,开启注解扫描 -> 注解属性->测试。
//操作1:创建User类和他的方法
package com.smxy.lj.anno;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
//操作3:注解属性
//代替<bean id="user" class="com.smxy.lj.anno.User"></bean>
@Component(value = "user")
@Scope(value = "prototype")
public class User {
public void add() {
System.out.println("User----add");
}
}
<!-- 操作2 :配置文件ApplicationContext.xml-->
<?xml version="1.0" encoding="UTF-8"?>
<!-- 引入新约束——context -->
<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"
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">
<!-- 开启注解扫描 -->
<!-- base-package代表扫描哪个位置,大概是注解的位置,可以写具体也可以写模糊 -->
<context:component-scan base-package="com.smxy.lj">
</context:component-scan>
</beans>
//操作4:测试
public class TestAnno {
private ApplicationContext context;
@Test
public void testUser(){
context = new ClassPathXmlApplicationContext("ApplicationContext.xml");
//user为User类的注解属性
User user = (User)context.getBean("user");
System.out.println(user);
user.add();
}
}
3. 注解注入属性
案例1:在service类中得到dao类中的操作
创建俩个类:1)UserService.class和UserDao.class
2)配置文件,引入约束
3)注解属性
4)注入
package com.smxy.lj.anno;
@Service(value="userService")
public class UserService {
//定义dao属性
//在dao属性上使用注解,完成对象注入
//Autowired(自动装配/注入)
@Autowired
private UserDao userDao;
private BookDao bookDao;
public void add(){
System.out.println("servicce---");
userDao.add();
}
}
//UserDao.class
package com.smxy.lj.anno;
@Component(value="userDao")
public class UserDao {
public void add(){
System.out.println("dao---");
}
}
@Test
public void testUser(){
//测试注入
UserService service = (UserService)context.getBean("service");
System.out.println(service);
service.add();
}
案例2:在service类中得到dao类中的操作
创建俩个类:1)Service.class和UserDao.class和BookDao.class
2)配置文件,引入约束
3)注解属性
4)注入
package com.smxy.lj.anno;
@Service(value="service")
public class Service {
//注入UserDao,name对应UserDao注解对应的value值
@Resource(name="userDao")
private UserDao userDao;
//注入BookDao,name对应BookDao注解对应的value值
@Resource(name="bookDao")
private BookDao bookDao;
//Service 的方法
public void add(){
System.out.println("servicce---");
//调用dao方法
userDao.add();
bookDao.buy();
}
}
//UserDao就用案例1的
//创建BookDao.class
package com.smxy.lj.anno;
@Component(value="bookrDao")
public class BookDao {
public void buy(){
System.out.println("----bookDao");
}
}
/**
*直接用案例1的测试方法
**/
案例3
将例2用注解和配置文件混合使用的方式实现
//配置文件———bean2.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: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.xsd">
<!-- 开启注解扫描 -->
<context:component-scan base-package="com.smxy.lj"></context:component-scan>
<!-- 配置对象 -->
<bean id="userDao" class="com.smxy.lj.anno.UserDao"></bean>
<bean id="bookDao" class="com.smxy.lj.anno.BookDao"></bean>
<bean id="service" class="com.smxy.lj.anno.UserService"></bean>
</beans>
//在Service.class
package com.smxy.lj.anno;
public class UserService {
//1d定义dao类,在dao属性上使用注解完成对象注入
@Resource(name="userDao")//dao用注解方式对应的属性值
private UserDao userDao;
@Resource(name="bookDao")
private BookDao bookDao;
public void add(){
System.out.println("servicce---");
userDao.add();
bookDao.buy();
}
}
@Test
public void testUser(){
context = new ClassPathXmlApplicationContext("bean2.xml");
//测试注入
UserService service = (UserService)context.getBean("service");
service.add();
}
【创建对象在配置文件中完成,注入属性用注解方式】
AOP(面向切面)
采用横向抽取机制,取代传统的纵向继承体制重复性代码
Aop的概述
- 涵义:面向切面(方面)编程。
- 目的:采用横向抽取机制来扩展代码,而不是通过修改代码来实现。
- 原理:底层使用动态代理方式实现。
Aop的术语
名称 | 涵义 | 其它 |
---|---|---|
连接点(Pointcut) | 类中可以被增强的方法 | |
切入点 | 在类中实际被增强的方法 | |
通知/增强(Advice) | 实际增强的逻辑(功能),扩展的功能就称为增强 | 前置通知:在方法之前执行;后置通知:在方法之后执行;最终通知:在后置之后执行;环绕通知:方法之前,之后都执行 |
切面(Aspect) | 把增强应用到具体方法上(切入点)的过程叫切面。 |
Aop的使用
有接口:使用jdk动态代理,创建接口实现类代理对象
使用动态代理方式
创建接口实现类的代理对象
,增强方法。
Proxy.newProxyInstance(loader, interfaces, this)
无接口:使用cglib动态代理,创建接口实现类代理对象
使用动态代理方式
创建类的子类代理对象
,在子类中调用父类的方法{super()方法}
Aop的使用——AspectJ(面向切面的框架)
AspectJ(面向切面的框架),不属于Spring,只是和Spring一起使用来进行aop操作
两种方式:基于aspectJ的xml配置方式和基于aspectJ的注解方式。
案例:Book为被增强的类,增强其add()方法,MyBook为增强的类
方式一:用AspectJ的配置文件方式实现
1.步骤
1)导入相关的jar包
spring-aop-4.3.16.RELE
aopalliance-1.0
spring-aspects-4.3.16.RELE
aspectjweaver
2)创建Book.class,MyBook.class
//Book.class
package com.smxy.lj.aspectJ;
public class Book {
public void add(){
System.out.println("Book---add");
}
}
//MyBook.class
package com.smxy.lj.aspectJ;
public class MyBook {
public void before(){
System.out.println("MyBook---before");
}
}
3)创建配置文件,导入aop的约束
<!-- 创建配置文件,bean3.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"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
<!-- 1.配置对象 -->
<bean id="book" class="com.smxy.lj.aspectJ.Book"></bean>
<bean id="myBook" class="com.smxy.lj.aspectJ.MyBook"></bean>
<!-- 2.配置aop操作 -->
<aop:config>
<!--2.1 配置切入点 -->
<aop:pointcut expression="execution(* com.smxy.lj.aspectJ.Book.*(..))"
id="pointcut" />
<!--2.2 配置切面,将增强用到方法上面。ref为增强的对象 -->
<aop:aspect ref="myBook">
<!-- 配置增强类型 method:增强类里使用哪个方法作为前置增强; pointcut-ref:把增强用到哪个切入点上 -->
<aop:before method="before" pointcut-ref="pointcut" />
</aop:aspect>
</aop:config>
</beans>
//效果测试(MyBook的before()先运行,Book的add()后运行)
@Test
public void test(){
ApplicationContext context = new ClassPathXmlApplicationContext("bean3.xml");
Book book = (Book)context.getBean("book");
book.add();
}
结果输出
前置增强
环绕通知---前
Book---add
环绕通知---后
后置增强
方式二:用AspectJ的注解方式实现
1.步骤:引用以上俩个类,修改配置文件
1)开启aop操作(自动代理)
2)创建book和myBook
<!-- 创建配置文件,bean4.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-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
<!-- 1.开启aop操作(自动代理) -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
<!-- 2.创建对象 -->
<bean id="book" class="com.smxy.lj.aspectJ.Book"></bean>
<bean id="myBook" class="com.smxy.lj.aspectJ.MyBook"></bean>
</beans>
3)在增强的类上使用注解方式加强
//增强Book的add()方法,在增强类MyBook.class中修改
@Aspect
public class MyBook {
//在方法上面使用真正的注解增强配置
@Before(value = "execution(* com.smxy.lj.aspectJ.Book.*(..))")
public void before(){
System.out.println("前置增强");
}
}
4)测试,直接使用方式一的测试类。结果输出:
前置增强
Book---add