建立依赖于应用程序位置的Spring Bean

时间:2015-12-10 02:19:12

标签: java spring-mvc azure-cloud-services

我正在开发Spring的Web MVC实现。我在配置期间建立一个表示数据库连接的Bean。连接Bean初始化为一个布尔值,表示这是测试还是实时环境,它控制连接到哪个相应的数据库。因此,我的配置包含如下内容:

create or replace FUNCTION save_hr_030_040(p_event_record_id       number,
                       p_share_log_id          number,
                       p_oa_flow_doc_header_id number,
                       p_created_by            number) return number is
v_data_line_id        number;
v_total_amount        number;
v_annual_vct_hour     number;
v_ot_vct_hour         number;
v_annual_vct_req_hour number;
v_ot_vct_req_hour     number;
v_string_date         varchar(100);
e_req_hour_error exception;
e_req_hour_error1 exception;
v_num                 number;
    begin_diff varchar2(8);     --You cannot declare inside BEGIN/END, you can only declare in the declaration section
    diff       varchar2(8);
    holiday_begin_date   number;
    holiday_end_date     number;

begin
select count(*) 
into v_num 
from user_tables 
where table_name = 'temp_line';
if v_num < 1 then 
if v_num < 1 then 
  execute immediate 'CREATE GLOBAL TEMPORARY TABLE temp_line ( 
   holiday_id VARCHAR2(6),
   holiday_begin_date DATE,
   holiday_begin_hour VARCHAR2(6),
   holiday_begin_min VARCHAR2(6),
   holiday_end_date DATE,
   holiday_end_hour VARCHAR2(6),
   holiday_end_min VARCHAR2(6)
  ) ON COMMIT PRESERVE ROWS'; 
  end if;
execute immediate ('FOR recitem IN(select * from oa_tplt019_line_01_v l where l.oa_flow_doc_header_id = p_oa_flow_doc_header_id); 


LOOP 
insert into temp_line(holiday_id,holiday_begin_date,holiday_begin_hour,holiday_begin_min,holiday_end_date, holiday_end_hour,holiday_end_min)
values
(recitem.C_025,recitem.C_027,recitem.C_028,recitem.C_029,recitem.C_030,recitem.D_001,reitem.D_002)  ENDLOOP;');   --remove extra '`' 

LOOP
select nvl(l.holiday_begin_date, 0),nvl(l.holiday_end_date, 0)
into holiday_begin_date,holiday_end_date
from temp_line l;

begin_diff := holiday_begin_date - sys_date;   --missing semi colon
diff :=  holiday_end_date - holiday_begin_date; --missing semi colon
IF begin_diff > 3 then
  raise e_req_hour_error;
  END IF;
IF diff < 0 then
  raise e_req_hour_error1;
  END IF; END LOOP;   --These are not ENDIF and ENDLOOP, you need to add space betwween them

      end if;
      end;

我正在使用Azure Toolkit for Eclipse将此网络应用程序部署为microsoft azure作为云服务。我有两个独立的云应用程序,代表相应的测试和现场环境。

我的问题是我无论如何都无法想到以编程方式确定它是否是实时环境。理想情况下,我可以从请求中提取基URI并使用它来确定它,但在配置时该信息不可用。

也许我的做法完全错了。任何帮助表示赞赏!

2 个答案:

答案 0 :(得分:1)

你的豆子不应该知道你的环境。这是糟糕的设计。如果bean使用完全相同的逻辑,则应该通过类路径(src / main / resources)上的xxx.properties文件注入连接属性,并且此文件在每个环境的代码分支中应具有不同的值。因此,在您的存储库中,您将进行“测试”。分支机构和现场直播分支,其中connection.properties位于相同的路径src / main / resource中,但它们具有不同的键/值对。这会将您的配置与实际代码分离。

所以这样(来自Spring文档)

@Configuration
public class AppConfig {

    @Value("${jdbc.url}")
    private String url;

    @Value("${jdbc.username}")
    private String username;

    @Value("${jdbc.password}")
    private String password;

    @Bean
    public DataSource dataSource() {
        return new DriverManagerDataSource(url, username, password);
    }
} 

和src / main / resources

中的jdbc.properties文件
#contents of jdbc.properties ( on 'test' branch )
jdbc.url=someHost.com/db
jdbc.username=root
jdbc.password=secret

#contents of jdbc.properties ( on 'live' branch )
jdbc.url=someHost.com/db_prod
jdbc.username=asdasdasda
jdbc.password=as3432543$$#@%@#

有几种方法可以在春季管理属性...我在下面提供了链接,演示了如何执行此操作:

http://www.summa-tech.com/blog/2009/04/20/6-tips-for-managing-property-files-with-spring

http://blog.jamesdbloom.com/UsingPropertySourceAndEnvironment.html

http://www.petrikainulainen.net/programming/spring-framework/spring-from-the-trenches-injecting-property-values-into-configuration-beans/

答案 1 :(得分:0)

所以我想出了一个解决方案..它不是很优雅,但它确实有用。

我使用以下命令使控制器可用于ConnectionManager类:

@Autowired
protected ConnectionManager manager;

我的解决方案是通过方法而不是直接访问连接管理器。该方法评估请求并决定是否需要更新管理器的环境。即:

@Autowired
private ConnectionManager manager;

@Autowired
private HttpServletRequest context;

/*
 * Return an updated manager instance
 */
protected ConnectionManager getConnectionManager(){
    /*
    ... Logic that evaluates the HttpServletRequest 
    ... and changes the ConnectionManager accordingly.
    */
    return manager;
}

这个逻辑在于我的所有控制器都扩展的抽象控制器类。这使得所有控制器都可以轻松访问管理器的更新版本。

显然这并不完美,并且为需要访问连接管理器的任何请求增加了额外的开销,但我没有找到任何替代方案。

相关问题