4.spring:@Profile,AOP

Profile:

可以根据当前的环境,动态激活和切换一系列的组件功能
指定组件在那个环境下才能被注册到容器中,不指定任何环境下都能注册到

 

1.加了环境标识的bean只有环境激活的时候才能注册到容器中
    默认是default ,@Profile("default") 才能加入到环境中
2.还可以下载类上,只有在当时的环境下,整个类的方法才会生效
3.默认没标识的bean在,任何环境下都是加载的
db.user=root
db.password=1234
db.jdbcUrl=jdbc:mysql://localhost:3306/users
db.drivetClass=com.mysql.jdbc.Driver

 

 

@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;
     }
}
@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");可以同时写多个
mainConfigProfile
devDatasource
此时可以看出 app.getEnvironment().setActiveProfiles("dev");
这里只添加了一个环境,所以得到在dev环境下的bean,其余的均不会装配到bean容器中

 

此种情况下,也会自动装入到bean容器
@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 开启基于注解模式动态代理

 

//切面类

@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);
     }
}

 

//业务类

public class MathCAL {
     public int div(int i,int j){
           System.out.println("正在计算.....");
           return (i / j);
     }
}
@EnableAspectJAutoProxy
@Configuration
public class MainAopConfig {
     //业务逻辑类
     @Bean
     public MathCAL mathCal(){
           return new MathCAL();
     }
     //切面类
     @Bean
     public LogAspects logAspect(){
           return new LogAspects();
     }
     
}

 

     @Test
     public void test(){
           AnnotationConfigApplicationContext app = new 
         AnnotationConfigApplicationContext(MainAopConfig.class); MathCAL math = app.getBean(MathCAL.class); math.div(2, 0); }

 

开始计算:div--[2, 0]
正在计算.....
结束计算
Exception:java.lang.ArithmeticException: / by zero

 

 

AOP原理:
@EnableAspectJAutoProxy
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
...
}
class AspectJAutoProxyRegistrar implements  ImportBeanDefinitionRegistrar {
...
}

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

 

posted @ 2018-12-12 19:12  MrChengs  阅读(329)  评论(0编辑  收藏  举报