Fork me on GitHub

Spring:@Profile,AOP

Profile:

可以根据当前的环境,动态激活和切换一系列的组件功能

指定组件在那个环境下才能被注册到容器中,不指定任何环境下都能注册到

1.加了环境标识的bean只有环境激活的时候才能注册到容器中

默认是default ,@Profile(“default”) 才能加入到环境中

2.还可以下载类上,只有在当时的环境下,整个类的方法才会生效

3.默认没标识的bean在,任何环境下都是加载的

1
2
3
4
db.user=root
db.password=1234
db.jdbcUrl=jdbc:mysql://localhost:3306/users
db.drivetClass=com.mysql.jdbc.Driver
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
@PropertySource("classpath:/db.properties")
@Configuration
public class MainConfigProfile {
@Value("${db.user}")
private String user;
@Value("${db.password}")
private String pwd;
@Value("${db.jdbcUrl}")
private String jdbcUrl;
@Value("${db.drivetClass}")
private String DriverClass;

@Profile("test")
@Bean("testDatasource")
public ComboPooledDataSource datasource() throws Exception{
ComboPooledDataSource datasource = new ComboPooledDataSource();
datasource.setUser(user);
datasource.setPassword(pwd);
datasource.setJdbcUrl(jdbcUrl);
datasource.setDriverClass(DriverClass);
return datasource;
}

@Profile("dev")
@Bean("devDatasource")
public ComboPooledDataSource datasource1() throws Exception{
ComboPooledDataSource datasource = new ComboPooledDataSource();
datasource.setUser(user);
datasource.setPassword(pwd);
datasource.setJdbcUrl("jdbc:mysql://localhost:3306/ssm");
datasource.setDriverClass(DriverClass);
return datasource;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@Test
public void test7(){
//创建一个application
AnnotationConfigApplicationContext app =
new AnnotationConfigApplicationContext();
//设置环境
app.getEnvironment().setActiveProfiles("dev");
//注册配置类
app.register(MainConfigProfile.class);
//启动刷新容器
app.refresh();

String[] names = app.getBeanDefinitionNames();
for(String name : names){
System.out.println(name);
}
}

注:app.getEnvironment().setActiveProfiles(“dev”,”test”);可以同时写多个

1
2
mainConfigProfile
devDatasource

此时可以看出 app.getEnvironment().setActiveProfiles(“dev”);

这里只添加了一个环境,所以得到在dev环境下的bean,其余的均不会装配到bean容器中

此种情况下,也会自动装入到bean容器

1
2
3
4
5
6
7
8
9
10
@Profile("default")
@Bean("devDatasource")
public ComboPooledDataSource datasource1() throws Exception{
ComboPooledDataSource datasource = new ComboPooledDataSource();
datasource.setUser(user);
datasource.setPassword(pwd);
datasource.setJdbcUrl("jdbc:mysql://localhost:3306/ssm");
datasource.setDriverClass(DriverClass);
return datasource;
}

AOP:

在程序运行期间,能够动态的将某段代码切入到指定的位置进行编程

1.导入aop模块:aspects

2.业务逻辑类

3.日志切面类:

前置通知:@Before

后置通知: @After

异常通知:@AfterReturning

返回通知:@AfterThrowing

环绕通知:@Around

4.将切面类和业务逻辑加入容器里

5.告诉spring那个类是切面类

切面类加一个注解@Aspect:告诉spring当前类是一个切面类

6.给配置类家@EnableAspectJAutoProxy 开启基于注解模式动态代理

//切面类

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
@Aspect
public class LogAspects {

//抽取公共的接入点
//本类的引用:pointCut()
//外部类的引用:coom.MrChengs.aop.LogAspects.pointCut()
@Pointcut("execution(public int coom.MrChengs.aop.MathCAL.*(..))")
public void pointCut(){};

//目标方法之前切入;切入点表达式(指定在那个方面切入)
//JoinPoint这个参数一定要出现在参数表的第一位,否则会报错
@Before("pointCut()")
public void loginStart(JoinPoint joinpoint){
//拿到执行的数据
Object [] args = joinpoint.getArgs();

System.out.println("开始计算:"+joinpoint.getSignature().getName()+"--"+Arrays.asList(args));
}

//无论正常还是异常结束
@After("pointCut()")
public void loginEnd(){
System.out.println("结束计算");
}
@AfterReturning(value="pointCut()",returning="res")
public void logReturn(int res ){
System.out.println("结果L:" + res);
}
@AfterThrowing(value ="pointCut()",throwing="exc")
public void loginException(Exception exc){
System.out.println("Exception:" + exc);
}
}

//业务类

1
2
3
4
5
6
public class MathCAL {
public int div(int i,int j){
System.out.println("正在计算.....");
return (i / j);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@EnableAspectJAutoProxy
@Configuration
public class MainAopConfig {
//业务逻辑类
@Bean
public MathCAL mathCal(){
return new MathCAL();
}
//切面类
@Bean
public LogAspects logAspect(){
return new LogAspects();
}

}
1
2
3
4
5
6
7
8
@Test
public void test(){
AnnotationConfigApplicationContext app = new
         AnnotationConfigApplicationContext(MainAopConfig.class);

MathCAL math = app.getBean(MathCAL.class);
math.div(2, 0);
}
1
2
3
4
5
> 开始计算:div--[2, 0]
> 正在计算.....
> 结束计算
> Exception:java.lang.ArithmeticException: / by zero
>

AOP原理:

@EnableAspectJAutoProxy

1
2
3
4
5
6
7
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
...
}
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
...
}

利用AspectJAutoProxyRegistrar自定义为容器注入bean

原文链接

相关文章

微信打赏

赞赏是不耍流氓的鼓励

评论系统未开启,无法评论!