Используя классы Java в Grails

Вы можете использовать отражение .

import scala.reflect.ClassTag
import scala.reflect.runtime.universe._

abstract class FieldRequestSupport[SelfType <: Product : ClassTag : TypeTag] {
    self: SelfType =>

    private val classFieldsAccessors: Map[String, MethodSymbol] = typeOf[SelfType].members.collect({
        case m: MethodSymbol if m.isCaseAccessor => m
    }).flatMap(symbol => TermName.unapply(symbol.name).map((_, symbol)))(collection.breakOut)
    private val classMirror: Mirror = runtimeMirror(getClass.getClassLoader)

    def requestField(fieldName: String): Option[Any] = {
        classFieldsAccessors.get(fieldName).map(
            symbol => classMirror.reflect(self).reflectField(symbol).get
        )
    }
}

case class Person(name: String, age: Int) extends FieldRequestSupport[Person]

object Test extends App {
    val person = Person("Bob", 26)
    println(person.requestField("name")) //will print Some(Bob)
    println(person.requestField("age")) //will print Some(26)
    println(person.requestField("qqq")) //will print None
}

7
задан RN. 30 March 2010 в 20:19
поделиться

3 ответа

Вы действительно хотите / должны использовать Grails, а не просто Groovy?

Grails действительно не то, что вы можете использовать для добавления части в существующее веб-приложение. Подход «соглашение вместо конфигурации» означает, что вам в значительной степени придется играть по правилам Grails, иначе нет смысла его использовать. И одно из этих правил состоит в том, что объекты предметной области представляют собой классы Groovy, которые сильно «улучшены» средой выполнения Grails.

Возможно, они смогут расширить существующие классы Java, но я бы не стал на это делать ставку - и все части Spring и Hibernate в вашем существующем приложении пришлось бы отказаться, или, по крайней мере, вам пришлось бы потратить много усилий, чтобы заставить их работать в Grails. Вы будете бороться с фреймворком, а не извлекать из него выгоду.

ИМО, у вас есть два варианта:

  • Перепишите свое приложение с нуля в Grails, повторно используя как можно больше существующего кода.
  • Сохраните приложение как есть и добавляйте новые вещи в Groovy без использования Grails.

Последнее, вероятно, лучше в ваша ситуация. Grails предназначен для очень быстрого создания новых веб-приложений, вот в чем он заключается. Добавление чего-либо в существующее приложение - не то, для чего оно было создано.

РЕДАКТИРОВАТЬ: Что касается пояснения в комментариях: если вы планируете написать в основном интерфейс ввода / обслуживания данных для данных, используемых другим приложением, и использовать БД в качестве единственного канала связи между ними, это может действительно хорошо работать с Grails; его, безусловно, можно настроить на использование существующей схемы БД, а не на создание собственной схемы из классов домена (хотя последнее требует меньше усилий).

4
ответ дан 6 December 2019 в 06:51
поделиться

В этом посте представлены некоторые предложения по использованию grails для обертывания существующих классов Java в веб-фреймворк .

3
ответ дан 6 December 2019 в 06:51
поделиться

Knowing just how well Groovy and Grails excel at integrating with existing Java code, I think I might be a bit more optimistic than Michael about your options.

First thing is that you're already using Spring and Hibernate, and since your domain classes are already POJOs they should be easy to integrate with. Any Spring beans you might have can be specified in an XML file as usual (in grails-app/conf/spring/resources.xml) or much more simply using the Spring bean builder feature of Grails. They can then be accessed by name in any controller, view, service, etc. and worked with as usual.

Here are the options, as I see them, for integrating your domain classes and database schema:

  • Bypass GORM and load/save your domain objects exactly as you're already doing.

    Grails doesn't force you to use GORM, so this should be quite straightforward: create a .jar of your Java code (if you haven't already) and drop it into the Grails app's lib directory. If your Java project is Mavenized, it's even easier: Grails 1.1 works with Maven, so you can create a pom.xml for your Grails app and add your Java project as a dependency as you would in any other (Java) project.

    Either way you'll be able to import your classes (and any supporting classes) and proceed as usual. Because of Groovy's tight integration with Java, you'll be able to create objects, load them from the database, modify them, save them, validate them etc. exactly as you would in your Java project. You won't get all the conveniences of GORM this way, but you would have the advantage of working with your objects in a way that already makes sense to you (except maybe with a bit less code thanks to Groovy). You could always try this option first to get something working, then consider one of the other options later if it seems to make sense at that time.

    One tip if you do try this option: abstract the actual persistence code into a Grails service (StorageService perhaps) and have your controllers call methods on it rather than handling persistence directly. This way you could replace that service with something else down the road if needed, and as long as you maintain the same interface your controllers won't be affected.

  • Create new Grails domain classes as subclasses of your existing Java classes.

    This could be pretty straightforward if your classes are already written as proper beans, i.e. with getter/setter methods for all their properties. Grails will see these inherited properties as it would if they were written in the simpler Groovy style. You'll be able to specify how to validate each property, using either simple validation checks (not null, not blank, etc.) or with closures that do more complicated things, perhaps calling existing methods in their POJO superclasses.

    You'll almost certainly need to tweak the mappings via the GORM mapping DSL to fit the realities of your existing database schema. Relationships would be where it might get tricky. For example, you might have some other solution where GORM expects a join table, though there may even be a way to work around differences such as these. I'd suggest learning as much as you can about GORM and its mapping DSL and then experiment with a few of your classes to see if this is a viable option.

  • Have Grails use your existing POJOs and Hibernate mappings directly.

    I haven't tried this myself, but according to Grails's Hibernate Integration page this is supposed to be possible: "Grails also allows you to write your domain model in Java or re-use an existing domain model that has been mapped using Hibernate. All you have to do is place the necessary 'hibernate.cfg.xml' file and corresponding mappings files in the '%PROJECT_HOME%/grails-app/conf/hibernate' directory. You will still be able to call all of the dynamic persistent and query methods allowed in GORM!"

    Googling "gorm legacy" turns up a number of helpful discussions and examples, for example this blog post by Glen Smith (co-author of the soon-to-be-released Grails in Action) where he shows a Hibernate mapping file used to integrate with "the legacy DB from Hell". Grails in Action has a chapter titled "Advanced GORM Kungfu" which promises a detailed discussion of this topic. I have a pre-release PDF of the book, and while I haven't gotten to that chapter yet, what I've read so far is very good, and the book covers many topics that aren't adequately discussed in other Grails books.

Sorry I can't offer any personal experience on this last option, but it does sound doable (and quite promising). Whichever option you choose, let us know how it turns out!

19
ответ дан 6 December 2019 в 06:51
поделиться