Hi, I'm coming to all this a little late, I'm just back from vacation and I'm not sure I know exactly where the discussion is right now, I'm basing my feedback mostly on the wiki page. In my view we need to fit the following principals for creating annotations:
1. Everything that can be done in XML does not need to be expressible using annotations. 2. Annotation based programming should be there to make development trivial for the most common scenarios. 3. You should be able to mix annotations and XML, and if both exist XML trumps annotations. This allows changes to be made without recompiling code. 4. The annotations should be configuration by exception, so we should choose good defaults. A key benefit in my experience of using annotations is that the metadata is applied directly to the class to which it relates. If you put the annotations in a different class it seems that we are essentially creating a different serialisation of the xml, one that goes to .java files, which isn't something I think makes sense. So based on the wiki page here are my thoughts: 1. I like the bean annotation and I think it makes sense to apply it to a class. 2. I think the "id" should be optional if not specified we should default, perhaps default to the class name of the bean. 3. I don't think the args property of the Bean makes sense. First of all it applies to the constructor, so I would annotate the constructor, but in the second instance I'm not sure it makes sense to initialise values in annotations, you can already express that in Java code, so I think @Bean annotated classes should have a zero args constructor. 4. I don't think factory methods etc make sense for an @Bean annotation. I think you should annotate the factory component in that case. 5. Not 100% sure I see the point of annotating factories, but I don't feel too strongly. 6. Why is @Inject and @Reference used together? 7. I do not think there is any point in the @Inject(value="Hello FooBar") example, why wouldn't I just do private String value = "Hello FooBar"; it is more efficient and simpler code. 8. I think we should drop the @Blueprint annotation. This is for overriding the defaults in the spec which should be good enough in most scenarios. If someone wants to set these they can do this in a blueprint.xml that only specifies the defaults. Thanks Alasdair On 19 May 2010 02:44, Lin Sun <[email protected]> wrote: > Hi Guillaume, > > Thanks for the nice input. I think you have some excellent points > here on code reusability and easy for re-factor. I'll try modify the > annotation designs based on the discussions here and let you know when > I have an update. > > Lin > > On Tue, May 18, 2010 at 3:32 AM, Guillaume Nodet <[email protected]> wrote: >> That would be better imho. >> I still think that adding annotations containing values (or reference to >> names of other beans) on a class is a bad idea. The reason is that it makes >> this class not reusable at all, which imho is one of the main feature of >> blueprint. >> Doing that would led our users down this path and when further down, >> they'll see that they can't really reuse their beans without modifying >> them... >> >> Annotations on the classes are fine when they just say something about the >> bean: if they need to be injected with a value, if a method is the >> initialization / destroy method, etc ... >> >> Another point is that we should try to minimize the amount of information in >> order to make things easier to refactory, not harder. Currently, all the >> ids of beans for example are centrlized in the xml. Spreading them around >> will just make things harder to refactor. The @Bean annotation should be >> mostly optional, as it does not bring anything. The use of @PreDestroy and >> @PostConstruct on the method will also make it easier to change the method >> name, without having the change the init-method attribute on the bean >> annotation. >> >> I don't think the goal should be to stay too close to the xml >> configuration. While dealing with Java, we could also thing about some kind >> of DSL to build the configuration. >> >> In addition, we need to remain blueprint compliant and make sure we have >> something in the blueprint xml to indicate we want some extension parser. >> >> On Fri, May 14, 2010 at 19:48, Lin Sun <[email protected]> wrote: >> >>> >>> I wonder if we could use what we have now for simple, common cases, >>> while use a hybrid approach like below: >>> >>> 1) we allow users to annotate the class to define its behavior like >>> @Bean, @Service, @ReferenceListener like what we have right now. >>> 2) Optionally, we allow users to create a common configuration java >>> file to describe how they want to create instances with the values. >>> >>> For example: >>> >>> @Bean >>> public class BeanClass { >>> ... >>> } >>> >> >> Such annotations should not be mandatory I think. A bean is just an >> instance of a class. There's no load time weaving or anything going on at >> this point, so annotating it with a default annotation should be optional >> (if needed at all) >> >> >>> >>> @Bean(factoryRef="accountFactory", >>> factoryMethod="createAccount") >>> public class NewAccount { >>> ... >>> } >>> >> >> I really don't like this one either. If needed, this annotation should be >> on the createAccount method of the factory. >> >> >>> >>> // this class also gets to specify the blueprint global configuration >>> like defaultActivation, defaultTimeout, etc >>> @Blueprint(defaultActivation="eager", defaultTimeout=300, >>> defaultAvailability="optional") >>> public class BlueprintConfig { >>> >>> @Bean(id="myBean1") >>> public BeanClass beanClass1(){ >>> �...@inject @Bean(id="accountOne", ar...@arg(value="1") >>> NewAccount account; >>> .... >>> } >>> >>> @Bean(id="myBean2") >>> public BeanClass beanClass1(){ >>> �...@inject @Bean(id="accountOne", ar...@arg(value="2") >>> NewAccount account; >>> .... >>> } >>> } >>> >>> WDYT? >>> >>> >> The id of the bean could be inferred from the method name. >> What about the following configuration: >> >> @Blueprint >> public class MyConfig { >> >> �...@bean public BeanClass myBean1() { >> return new BeanClass(accountFactory.createAccount(1)); >> } >> >> �...@bean public BeanClass myBean2() { >> return new BeanClass(accountFactory().createAccount(2)); >> } >> >> �...@bean public AccountFactory accountFactory() { >> return new AccountFactory(); >> } >> } >> >> I suppose in order to respect scopes, we'd have to modify this class to >> intercept calls, so that the accountFactory() method would cache the value >> of the create account factory. >> >> I also think, that in order to support "custom namespace", we'd have to >> define annotations to put on other annotations, so that we can ask the >> namespace handler to help building the metadata. We also need to be able >> to inject values from outside to support config admin and property >> placeholders. >> >> -- >> Cheers, >> Guillaume Nodet >> ------------------------ >> Blog: http://gnodet.blogspot.com/ >> ------------------------ >> Open Source SOA >> http://fusesource.com >> > -- Alasdair Nottingham [email protected]
