1. 程式人生 > >4.spring:@Profile,AOP

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